From fef2b85e2d387deae06e91ff6ff93fee60d484f1 Mon Sep 17 00:00:00 2001 From: Artem Umerov Date: Wed, 17 May 2023 21:46:45 +0300 Subject: [PATCH] 27 27 --- .../main/kotlin/dev/ragnarok/fenrir/Extra.kt | 4 +- .../dev/ragnarok/fenrir/FcmListenerService.kt | 2 +- .../fenrir/activity/CreatePinActivity.kt | 2 +- .../fenrir/activity/DualTabPhotoActivity.kt | 6 +- .../fenrir/activity/EnterPinActivity.kt | 2 +- .../ragnarok/fenrir/activity/MainActivity.kt | 70 +- .../fenrir/activity/PhotoAlbumsActivity.kt | 4 +- .../fenrir/activity/PhotosActivity.kt | 4 +- .../activity/gifpager/GifPagerActivity.kt | 2 +- .../activity/gifpager/GifPagerPresenter.kt | 2 +- .../fenrir/activity/gifpager/IGifPagerView.kt | 2 +- .../dev/ragnarok/fenrir/api/impl/PollsApi.kt | 12 + .../fenrir/api/interfaces/IPollsApi.kt | 5 + .../ragnarok/fenrir/api/model/VKApiPoll.kt | 16 + .../fenrir/api/services/IPollsService.kt | 10 + .../fenrir/db/model/entity/PollDboEntity.kt | 21 + .../ragnarok/fenrir/dialog/PostShareDialog.kt | 2 +- .../ragnarok/fenrir/domain/IPollInteractor.kt | 4 + .../fenrir/domain/impl/PollInteractor.kt | 22 +- .../fenrir/domain/mappers/Dto2Entity.kt | 148 ++++- .../fenrir/domain/mappers/Dto2Model.kt | 127 +++- .../fenrir/domain/mappers/Entity2Model.kt | 17 + .../fenrir/domain/mappers/Model2Entity.kt | 82 ++- .../fenrir/fragment/DualTabPhotosFragment.kt | 8 +- .../fenrir/fragment/PreferencesFragment.kt | 2 +- .../fragment/SecurityPreferencesFragment.kt | 2 +- .../AbsAttachmentsEditFragment.kt | 19 +- .../AttchmentsEditorAdapter.kt | 4 +- .../commentcreate/CommentCreateFragment.kt | 2 - .../LocalAudioAlbumsFragment.kt | 2 +- .../fragment/base/BaseMvpDialogFragment.kt | 25 +- .../fragment/base/RecyclerBindableAdapter.kt | 4 + .../fragment/comments/CommentsFragment.kt | 40 +- .../CommunityControlFragment.kt | 10 +- .../communityban/CommunityBanEditFragment.kt | 2 +- .../communityban/CommunityBanEditPresenter.kt | 2 +- .../communityban/CommunityBannedAdapter.kt | 2 +- .../communityban/ICommunityBanEditView.kt | 2 +- .../CommunityBlacklistFragment.kt | 4 +- .../CommunityBlacklistPresenter.kt | 2 +- .../ICommunityBlacklistView.kt | 2 +- .../CommunityInfoContactsAdapter.kt | 2 +- .../CommunityInfoContactsFragment.kt | 2 +- .../CommunityInfoContactsPresenter.kt | 2 +- .../ICommunityInfoContactsView.kt | 2 +- .../CommunityInfoLinksAdapter.kt | 2 +- .../CommunityInfoLinksFragment.kt | 2 +- .../CommunityInfoLinksPresenter.kt | 2 +- .../ICommunityInfoLinksView.kt | 2 +- .../communitylinks/CommunityLinksAdapter.kt | 2 +- .../communitylinks/CommunityLinksFragment.kt | 2 +- .../communitylinks/CommunityLinksPresenter.kt | 2 +- .../communitylinks/ICommunityLinksView.kt | 2 +- .../CommunityManagerEditFragment.kt | 2 +- .../CommunityManagerEditPresenter.kt | 2 +- .../ICommunityManagerEditView.kt | 2 +- .../CommunityManagersAdapter.kt | 2 +- .../CommunityManagersFragment.kt | 2 +- .../CommunityManagersPresenter.kt | 2 +- .../ICommunityManagersView.kt | 2 +- .../CommunityMembersFragment.kt | 2 +- .../CommunityMembersPresenter.kt | 2 +- .../communitymembers/ICommunityMembersView.kt | 2 +- .../CommunityOptionsFragment.kt | 2 +- .../CommunityOptionsPresenter.kt | 2 +- .../communityoptions/ICommunityOptionsView.kt | 2 +- .../groupchats/GroupChatsAdapter.kt | 2 +- .../groupchats/GroupChatsFragment.kt | 2 +- .../groupchats/GroupChatsPresenter.kt | 2 +- .../groupchats/IGroupChatsView.kt | 2 +- .../IChatAttachmentAudiosView.kt | 6 - .../IChatAttachmentDocsView.kt | 6 - .../IChatAttachmentLinksView.kt | 6 - .../IChatAttachmentPostsView.kt | 6 - .../IChatAttachmentVideoView.kt | 6 - .../AbsDocumentPreviewActivity.kt | 2 +- .../AbsDocumentPreviewFragment.kt | 2 +- .../BaseDocumentPresenter.kt | 2 +- .../absdocumentpreview/IBasicDocumentView.kt | 2 +- .../fave/favephotos/FavePhotosAdapter.kt | 13 + .../feedbanned/FeedBannedFragment.kt | 2 +- .../feedbanned/FeedBannedPresenter.kt | 2 +- .../newsfeedcomments/INewsfeedCommentsView.kt | 2 +- .../NewsfeedCommentsAdapter.kt | 4 +- .../NewsfeedCommentsFragment.kt | 2 +- .../NewsfeedCommentsPresenter.kt | 2 +- .../NewsfeedMentionsFragment.kt | 6 +- .../NewsfeedMentionsPresenter.kt | 4 +- .../FeedbackPhotosAdapter.kt | 2 +- .../FeedbackVKOfficialAdapter.kt | 2 +- .../FeedbackVKOfficialFragment.kt | 2 +- .../FeedbackVKOfficialPresenter.kt | 2 +- .../IFeedbackVKOfficialView.kt | 2 +- .../fragment/messages/chat/ChatFragment.kt | 82 ++- .../fragment/messages/chat/ChatPresenter.kt | 40 +- .../fragment/messages/chat/IChatView.kt | 18 +- .../sheet/AbsPresenterBottomSheetFragment.kt | 2 +- .../sheet/AttachmentsBottomSheetAdapter.kt | 18 +- .../chat}/sheet/IMessageAttachmentsView.kt | 3 +- .../chat}/sheet/MessageAttachmentsFragment.kt | 46 +- .../sheet/MessageAttachmentsPresenter.kt | 7 +- .../ConversationFragmentFactory.kt | 16 +- .../AbsChatAttachmentsFragment.kt | 4 +- .../BaseChatAttachmentsPresenter.kt | 2 +- .../IBaseChatAttachmentsView.kt | 2 +- .../ChatAttachmentAudioPresenter.kt | 4 +- .../ConversationAudiosFragment.kt | 4 +- .../IChatAttachmentAudiosView.kt | 6 + .../ChatAttachmentDocsPresenter.kt | 4 +- .../ConversationDocsFragment.kt | 4 +- .../IChatAttachmentDocsView.kt | 6 + .../ChatAttachmentLinksPresenter.kt | 4 +- .../ConversationLinksFragment.kt | 9 +- .../IChatAttachmentLinksView.kt | 6 + .../AttachmentConversationType.kt | 27 + .../ConversationMultiAttachmentsFragment.kt | 614 +++++++++++++++++ .../ConversationMultiAttachmentsPresenter.kt | 472 ++++++++++++++ .../IConversationMultiAttachmentsView.kt | 37 ++ .../ChatAttachmentPhotoPresenter.kt | 4 +- .../ConversationPhotosFragment.kt | 4 +- .../IChatAttachmentPhotosView.kt | 4 +- .../ChatAttachmentPostsPresenter.kt | 4 +- .../ConversationPostsFragment.kt | 9 +- .../IChatAttachmentPostsView.kt | 6 + .../ChatAttachmentVideoPresenter.kt | 4 +- .../ConversationVideosFragment.kt | 4 +- .../IChatAttachmentVideoView.kt | 6 + .../messages/dialogs/DialogsFragment.kt | 20 +- .../messages/dialogs/DialogsPresenter.kt | 2 +- .../fragment/messages/dialogs/IDialogsView.kt | 2 +- .../CreatePhotoAlbumFragment.kt | 2 +- .../EditPhotoAlbumPresenter.kt | 4 +- .../createphotoalbum/IEditPhotoAlbumView.kt | 2 +- .../localimagealbums/ILocalPhotoAlbumsView.kt | 2 +- .../LocalImageAlbumsFragment.kt | 2 +- .../LocalPhotoAlbumsAdapter.kt | 2 +- .../LocalPhotoAlbumsPresenter.kt | 2 +- .../localphotos/ILocalPhotosView.kt | 2 +- .../localphotos/LocalPhotosAdapter.kt | 2 +- .../localphotos/LocalPhotosFragment.kt | 2 +- .../localphotos/LocalPhotosPresenter.kt | 2 +- .../photoallcomment/IPhotoAllCommentView.kt | 2 +- .../PhotoAllCommentFragment.kt | 2 +- .../PhotoAllCommentPresenter.kt | 2 +- .../vkphotoalbums/IPhotoAlbumsView.kt | 2 +- .../vkphotoalbums/PhotoAlbumsPresenter.kt | 2 +- .../vkphotoalbums/VKPhotoAlbumsAdapter.kt | 2 +- .../vkphotoalbums/VKPhotoAlbumsFragment.kt | 4 +- .../vkphotos/BigVKPhotosAdapter.kt | 2 +- .../{ => photos}/vkphotos/IVKPhotosView.kt | 2 +- .../{ => photos}/vkphotos/VKPhotosFragment.kt | 4 +- .../vkphotos/VKPhotosPresenter.kt | 2 +- .../{ => pin}/createpin/CreatePinFragment.kt | 2 +- .../{ => pin}/createpin/CreatePinPresenter.kt | 2 +- .../{ => pin}/createpin/ICreatePinView.kt | 2 +- .../{ => pin}/enterpin/EnterPinFragment.kt | 2 +- .../{ => pin}/enterpin/EnterPinPresenter.kt | 2 +- .../{ => pin}/enterpin/IEnterPinView.kt | 2 +- .../fenrir/fragment/poll/IPollView.kt | 3 +- .../fenrir/fragment/poll/PollFragment.kt | 19 +- .../fenrir/fragment/poll/PollPresenter.kt | 1 + .../createpoll/CreatePollDialogFragment.kt | 229 +++++++ .../createpoll/CreatePollFragment.kt | 67 +- .../createpoll/CreatePollPresenter.kt | 44 +- .../HorizontalPollBackgroundAdapter.kt | 77 +++ .../{ => poll}/createpoll/ICreatePollView.kt | 6 +- .../{ => poll}/voters/VotersFragment.kt | 2 +- .../{ => poll}/voters/VotersPresenter.kt | 2 +- .../marketview/IMarketViewView.kt | 2 +- .../marketview/MarketViewFragment.kt | 2 +- .../marketview/MarketViewPresenter.kt | 2 +- .../productalbums/IProductAlbumsView.kt | 2 +- .../productalbums/MarketAlbumAdapter.kt | 2 +- .../productalbums/ProductAlbumsFragment.kt | 2 +- .../productalbums/ProductAlbumsPresenter.kt | 2 +- .../newsfeedsearch/NewsFeedSearchFragment.kt | 2 +- .../search/wallsearch/WallSearchFragment.kt | 2 +- .../fragment/videos/VideosTabsFragment.kt | 2 +- .../localvideos/ILocalVideosView.kt | 2 +- .../localvideos/LocalVideosAdapter.kt | 2 +- .../localvideos/LocalVideosFragment.kt | 4 +- .../localvideos/LocalVideosPresenter.kt | 2 +- .../videoalbums/IVideoAlbumsView.kt | 2 +- .../videoalbums/VideoAlbumsFragment.kt | 2 +- .../videoalbums/VideoAlbumsNewAdapter.kt | 2 +- .../videoalbums/VideoAlbumsPresenter.kt | 2 +- .../IVideoAlbumsByVideoView.kt | 2 +- .../VideoAlbumsByVideoFragment.kt | 4 +- .../VideoAlbumsByVideoPresenter.kt | 2 +- .../videopreview/IVideoPreviewView.kt | 2 +- .../{ => videos}/videopreview/MenuAdapter.kt | 2 +- .../videopreview/VideoPreviewFragment.kt | 2 +- .../videopreview/VideoPreviewPresenter.kt | 2 +- .../{abswall => wall}/AbsWallFragment.kt | 34 +- .../{abswall => wall}/AbsWallPresenter.kt | 2 +- .../fragment/{abswall => wall}/IWallView.kt | 2 +- .../fragment/{abswall => wall}/WallAdapter.kt | 2 +- .../{ => wall}/groupwall/GroupWallFragment.kt | 6 +- .../groupwall/GroupWallPresenter.kt | 6 +- .../{ => wall}/groupwall/IGroupWallView.kt | 4 +- .../userdetails/IUserDetailsView.kt | 2 +- .../userdetails/UserDetailsFragment.kt | 2 +- .../userdetails/UserDetailsPresenter.kt | 2 +- .../{ => wall}/userwall/IUserWallView.kt | 4 +- .../{ => wall}/userwall/UserWallFragment.kt | 4 +- .../{ => wall}/userwall/UserWallPresenter.kt | 6 +- .../WallAttachmentsFragmentFactory.kt | 21 + .../AttachmentWallType.kt | 27 + .../IWallMultiAttachmentsView.kt | 39 ++ .../wallmultiattachments}/LinksAdapter.kt | 4 +- .../PhotoAlbumsAdapter.kt | 2 +- .../WallMultiAttachmentsFragment.kt | 597 +++++++++++++++++ .../WallMultiAttachmentsPresenter.kt | 442 +++++++++++++ .../IWallPostQueryAttachmentsView.kt | 2 +- .../WallPostQueryAttachmentsFragment.kt | 17 +- .../WallPostQueryAttachmentsPresenter.kt | 5 +- .../IWallSearchCommentsAttachmentsView.kt | 2 +- .../WallSearchCommentsAttachmentsFragment.kt | 15 +- .../WallSearchCommentsAttachmentsPresenter.kt | 5 +- .../{ => wall}/wallpost/IWallPostView.kt | 2 +- .../{ => wall}/wallpost/WallPostFragment.kt | 2 +- .../{ => wall}/wallpost/WallPostPresenter.kt | 2 +- .../WallAttachmentsFragmentFactory.kt | 45 -- .../IWallAudiosAttachmentsView.kt | 18 - .../WallAudiosAttachmentsFragment.kt | 187 ------ .../WallAudiosAttachmentsPresenter.kt | 192 ------ .../IWallDocsAttachmentsView.kt | 17 - .../WallDocsAttachmentsFragment.kt | 152 ----- .../WallDocsAttachmentsPresenter.kt | 143 ---- .../IWallLinksAttachmentsView.kt | 17 - .../WallLinksAttachmentsFragment.kt | 149 ----- .../WallLinksAttachmentsPresenter.kt | 143 ---- .../IWallPhotoAlbumAttachmentsView.kt | 17 - .../WallPhotoAlbumAttachmentsFragment.kt | 149 ----- .../WallPhotoAlbumAttachmentsPresenter.kt | 143 ---- .../IWallPhotosAttachmentsView.kt | 20 - .../WallPhotosAttachmentsFragment.kt | 185 ------ .../WallPhotosAttachmentsPresenter.kt | 186 ------ .../IWallPostCommentAttachmentsView.kt | 19 - .../WallPostCommentAttachmentsFragment.kt | 208 ------ .../WallPostCommentAttachmentsPresenter.kt | 210 ------ .../IWallVideosAttachmentsView.kt | 17 - .../WallVideosAttachmentsFragment.kt | 155 ----- .../WallVideosAttachmentsPresenter.kt | 145 ----- .../dev/ragnarok/fenrir/link/LinkHelper.kt | 2 +- .../EndlessRecyclerOnScrollListener.kt | 8 +- .../fenrir/longpoll/NotificationHelper.kt | 1 + .../media/music/MusicPlaybackController.kt | 8 +- .../dev/ragnarok/fenrir/model/AbsModelType.kt | 36 +- .../fenrir/model/ParcelableModelWrapper.kt | 6 +- .../kotlin/dev/ragnarok/fenrir/model/Poll.kt | 143 ++++ .../kotlin/dev/ragnarok/fenrir/place/Place.kt | 26 - .../dev/ragnarok/fenrir/place/PlaceFactory.kt | 28 +- .../fenrir/push/message/WallPostFCMMessage.kt | 2 +- .../fenrir/util/FindAttachmentType.kt | 3 +- .../fenrir/util/serializeble/json/Json.kt | 22 +- .../json/JsonContentPolymorphicSerializer.kt | 7 +- .../util/serializeble/json/JsonElement.kt | 45 +- .../serializeble/json/JsonElementBuilders.kt | 38 ++ .../json/internal/CharsetReader.kt | 17 +- .../json/internal/FormatLanguage.kt | 45 ++ .../json/internal/JsonIterator.kt | 5 +- .../json/internal/StreamingJsonDecoder.kt | 3 + .../json/internal/TreeJsonDecoder.kt | 7 +- .../json/internal/TreeJsonEncoder.kt | 9 +- .../json/internal/lexer/JsonLexer.kt | 3 + .../msgpack/MsgPackConfiguration.kt | 7 +- .../BaseMsgPackExtensionSerializer.kt | 2 +- .../msgpack/internal/MsgPackDecoder.kt | 3 + .../msgpack/internal/MsgPackEncoder.kt | 14 +- .../fenrir/view/PollGradientDrawable.kt | 122 ++++ .../fenrir/view/ProfileCoverDrawable.kt | 3 + .../fenrir/view/RecyclerViewSavedScroll.kt | 48 ++ .../fenrir/view/RoundCornerLinearView.kt | 29 +- .../src/main/res/drawable/photo_sizes.xml | 2 +- .../res/layout/bottom_sheet_attachments.xml | 11 +- .../layout/bottom_sheet_attachments_edit.xml | 17 +- .../main/res/layout/fragment_create_poll.xml | 216 +++--- .../layout/fragment_create_poll_dialog.xml | 216 ++++++ .../src/main/res/layout/fragment_poll.xml | 2 + .../res/layout/fragment_wall_attachments.xml | 25 +- ...t_wall_conversation_attachments_multi.xml} | 28 +- .../main/res/layout/item_poll_background.xml | 38 ++ .../layout/item_wall_attachments_recycler.xml | 6 + app_fenrir/src/main/res/menu/menu_chat.xml | 4 +- app_fenrir/src/main/res/values-be/strings.xml | 7 +- app_fenrir/src/main/res/values-ru/strings.xml | 9 +- app_fenrir/src/main/res/values/strings.xml | 7 +- .../filegallery/activity/CreatePinActivity.kt | 2 +- .../filegallery/activity/EnterPinActivity.kt | 2 +- .../fragment/SecurityPreferencesFragment.kt | 2 +- .../{ => pin}/createpin/CreatePinFragment.kt | 2 +- .../{ => pin}/createpin/CreatePinPresenter.kt | 2 +- .../{ => pin}/createpin/ICreatePinView.kt | 2 +- .../{ => pin}/enterpin/EnterPinFragment.kt | 2 +- .../{ => pin}/enterpin/EnterPinPresenter.kt | 2 +- .../{ => pin}/enterpin/IEnterPinView.kt | 2 +- .../EndlessRecyclerOnScrollListener.kt | 8 +- .../dev/ragnarok/filegallery/place/Place.kt | 26 - .../util/serializeble/json/Json.kt | 22 +- .../json/JsonContentPolymorphicSerializer.kt | 7 +- .../util/serializeble/json/JsonElement.kt | 45 +- .../serializeble/json/JsonElementBuilders.kt | 38 ++ .../json/internal/CharsetReader.kt | 17 +- .../json/internal/FormatLanguage.kt | 45 ++ .../json/internal/JsonIterator.kt | 5 +- .../json/internal/StreamingJsonDecoder.kt | 3 + .../json/internal/TreeJsonDecoder.kt | 7 +- .../json/internal/TreeJsonEncoder.kt | 9 +- .../json/internal/lexer/JsonLexer.kt | 3 + .../msgpack/MsgPackConfiguration.kt | 7 +- .../BaseMsgPackExtensionSerializer.kt | 2 +- .../msgpack/internal/MsgPackDecoder.kt | 3 + .../msgpack/internal/MsgPackEncoder.kt | 14 +- .../filegallery/view/RoundCornerLinearView.kt | 29 +- build.gradle | 10 +- .../main/java/com/github/luben/zstd/Zstd.java | 1 + .../github/luben/zstd/ZstdInputStream.java | 11 + .../zstd/ZstdInputStreamNoFinalizer.java | 8 + libfenrir/src/main/jni/CMakeLists.txt | 2 +- .../animation/libyuv/include/libyuv/convert.h | 15 + .../jni/animation/libyuv/include/libyuv/row.h | 237 ++++++- .../animation/libyuv/include/libyuv/version.h | 2 +- .../jni/animation/libyuv/source/convert.cc | 251 ++++++- .../animation/libyuv/source/convert_argb.cc | 245 +++++++ .../animation/libyuv/source/convert_from.cc | 24 + .../libyuv/source/convert_from_argb.cc | 104 ++- .../libyuv/source/planar_functions.cc | 52 ++ .../jni/animation/libyuv/source/rotate.cc | 8 + .../animation/libyuv/source/rotate_argb.cc | 8 + .../jni/animation/libyuv/source/row_any.cc | 35 + .../jni/animation/libyuv/source/row_common.cc | 6 +- .../jni/animation/libyuv/source/row_lsx.cc | 558 ++++++++++++++++ .../jni/animation/libyuv/source/row_rvv.cc | 484 +++++++++++++- .../jni/animation/libyuv/source/row_win.cc | 23 +- .../jni/animation/libyuv/source/scale_argb.cc | 13 + .../main/jni/audio/opus/libopus/celt/arch.h | 3 + .../jni/audio/opus/libopus/celt/arm/armcpu.c | 11 +- .../opus/libopus/celt/arm/pitch_neon_intr.c | 51 +- .../main/jni/audio/opus/libopus/celt/bands.c | 9 +- .../audio/opus/libopus/celt/celt_decoder.c | 65 +- .../audio/opus/libopus/celt/celt_encoder.c | 16 +- .../jni/audio/opus/libopus/celt/celt_lpc.c | 72 +- .../jni/audio/opus/libopus/celt/cpu_support.h | 5 +- .../jni/audio/opus/libopus/celt/ecintrin.h | 4 + .../jni/audio/opus/libopus/celt/fixed_debug.h | 71 +- .../audio/opus/libopus/celt/fixed_generic.h | 14 +- .../jni/audio/opus/libopus/celt/float_cast.h | 62 +- .../jni/audio/opus/libopus/celt/kiss_fft.h | 12 +- .../jni/audio/opus/libopus/celt/mathops.h | 6 +- .../main/jni/audio/opus/libopus/celt/modes.c | 3 + .../jni/audio/opus/libopus/celt/os_support.h | 1 - .../main/jni/audio/opus/libopus/celt/pitch.c | 23 +- .../main/jni/audio/opus/libopus/celt/rate.c | 2 + .../jni/audio/opus/libopus/celt/stack_alloc.h | 4 +- .../opus/libopus/celt/x86/celt_lpc_sse.h | 5 +- .../audio/opus/libopus/celt/x86/pitch_sse.h | 8 +- .../opus/libopus/celt/x86/pitch_sse4_1.c | 51 +- .../jni/audio/opus/libopus/celt/x86/x86cpu.c | 37 +- .../jni/audio/opus/libopus/celt/x86/x86cpu.h | 46 +- .../jni/audio/opus/libopus/include/opus.h | 4 +- .../audio/opus/libopus/include/opus_custom.h | 7 +- .../audio/opus/libopus/include/opus_defines.h | 8 +- .../main/jni/audio/opus/libopus/silk/CNG.c | 4 + .../jni/audio/opus/libopus/silk/LPC_fit.c | 3 +- .../jni/audio/opus/libopus/silk/MacroCount.h | 2 +- .../jni/audio/opus/libopus/silk/MacroDebug.h | 54 +- .../main/jni/audio/opus/libopus/silk/NSQ.c | 36 +- .../jni/audio/opus/libopus/silk/NSQ_del_dec.c | 40 +- .../main/jni/audio/opus/libopus/silk/PLC.c | 6 +- .../jni/audio/opus/libopus/silk/SigProc_FIX.h | 10 +- .../jni/audio/opus/libopus/silk/VQ_WMat_EC.c | 4 +- .../silk/arm/LPC_inv_pred_gain_neon_intr.c | 22 +- .../audio/opus/libopus/silk/bwexpander_32.c | 3 +- .../audio/opus/libopus/silk/control_codec.c | 2 +- .../main/jni/audio/opus/libopus/silk/debug.c | 12 +- .../main/jni/audio/opus/libopus/silk/debug.h | 25 +- .../audio/opus/libopus/silk/decode_frame.c | 1 - .../main/jni/audio/opus/libopus/silk/define.h | 1 + .../jni/audio/opus/libopus/silk/enc_API.c | 15 +- .../libopus/silk/fixed/LTP_scale_ctrl_FIX.c | 11 +- .../warped_autocorrelation_FIX_neon_intr.c | 9 +- .../libopus/silk/fixed/burg_modified_FIX.c | 8 +- .../libopus/silk/fixed/find_pred_coefs_FIX.c | 3 +- .../opus/libopus/silk/fixed/vector_ops_FIX.c | 2 +- .../silk/fixed/x86/burg_modified_FIX_sse4_1.c | 69 +- .../silk/fixed/x86/vector_ops_FIX_sse4_1.c | 43 +- .../libopus/silk/float/LTP_scale_ctrl_FLP.c | 10 +- .../libopus/silk/float/find_pred_coefs_FLP.c | 3 +- .../opus/libopus/silk/float/wrappers_FLP.c | 10 +- .../main/jni/audio/opus/libopus/silk/main.h | 60 +- .../jni/audio/opus/libopus/silk/meson.build | 63 ++ .../libopus/silk/mips/NSQ_del_dec_mipsr1.h | 410 ------------ .../opus/libopus/silk/mips/macros_mipsr1.h | 92 --- .../libopus/silk/mips/sigproc_fix_mipsr1.h | 60 -- .../audio/opus/libopus/silk/stereo_LR_to_MS.c | 8 +- .../audio/opus/libopus/silk/stereo_MS_to_LR.c | 4 +- .../silk/tests/test_unit_LPC_inv_pred_gain.c | 129 ---- .../jni/audio/opus/libopus/silk/typedef.h | 3 + .../libopus/silk/x86/NSQ_del_dec_sse4_1.c | 180 +++-- .../audio/opus/libopus/silk/x86/NSQ_sse4_1.c | 213 +++--- .../opus/libopus/silk/x86/SigProc_FIX_sse.h | 49 +- .../audio/opus/libopus/silk/x86/VAD_sse4_1.c | 28 +- .../opus/libopus/silk/x86/VQ_WMat_EC_sse4_1.c | 189 +++--- .../audio/opus/libopus/silk/x86/main_sse.h | 237 ++++--- .../opus/libopus/silk/x86/x86_silk_map.c | 91 ++- .../jni/audio/opus/libopus/src/analysis.c | 2 + .../jni/audio/opus/libopus/src/opus_decoder.c | 15 +- .../jni/audio/opus/libopus/src/opus_encoder.c | 107 ++- .../libopus/src/opus_multistream_decoder.c | 7 +- .../libopus/src/opus_multistream_encoder.c | 9 +- .../opus/libopus/src/repacketizer_demo.c | 44 +- .../src/main/jni/compress/zstd/jni_zstd.c | 11 + .../lottie/rapidjson/internal/biginteger.h | 2 +- .../src/lottie/rapidjson/internal/diyfp.h | 2 +- .../rlottie/src/lottie/rapidjson/pointer.h | 14 +- libfenrir/src/main/jni/thorvg/inc/thorvg.h | 104 ++- .../thorvg/src/lib/sw_engine/tvgSwCommon.h | 11 +- .../thorvg/src/lib/sw_engine/tvgSwRaster.cpp | 616 +++++++++++------- .../thorvg/src/lib/sw_engine/tvgSwRasterAvx.h | 20 +- .../thorvg/src/lib/sw_engine/tvgSwRasterC.h | 65 +- .../src/lib/sw_engine/tvgSwRasterNeon.h | 20 +- .../src/lib/sw_engine/tvgSwRasterTexmap.h | 44 +- .../lib/sw_engine/tvgSwRasterTexmapInternal.h | 15 +- .../src/lib/sw_engine/tvgSwRenderer.cpp | 86 ++- .../thorvg/src/lib/sw_engine/tvgSwRenderer.h | 5 +- .../src/main/jni/thorvg/src/lib/tvgPaint.cpp | 13 +- .../main/jni/thorvg/src/lib/tvgPicture.cpp | 10 +- .../main/jni/thorvg/src/lib/tvgPictureImpl.h | 35 +- .../src/main/jni/thorvg/src/lib/tvgRender.h | 43 +- .../main/jni/thorvg/src/lib/tvgSceneImpl.h | 12 +- .../jni/thorvg/src/lib/tvgTaskScheduler.h | 2 +- .../thorvg/src/loaders/raw/tvgRawLoader.cpp | 3 +- .../thorvg/src/loaders/svg/tvgSvgLoader.cpp | 11 + .../decoder/ffmpeg/FfmpegAudioRenderer.kt | 38 +- 435 files changed, 9199 insertions(+), 5368 deletions(-) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/CommunityControlFragment.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityban/CommunityBanEditFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityban/CommunityBanEditPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityban/CommunityBannedAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityban/ICommunityBanEditView.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityblacklist/ICommunityBlacklistView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt (87%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt (82%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitylinks/CommunityLinksAdapter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitylinks/CommunityLinksFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitylinks/CommunityLinksPresenter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitylinks/ICommunityLinksView.kt (82%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt (90%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanagers/CommunityManagersAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanagers/CommunityManagersFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanagers/CommunityManagersPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymanagers/ICommunityManagersView.kt (90%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymembers/CommunityMembersFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymembers/CommunityMembersPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communitymembers/ICommunityMembersView.kt (88%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityoptions/CommunityOptionsFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityoptions/CommunityOptionsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/communitycontrol/communityoptions/ICommunityOptionsView.kt (93%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/groupchats/GroupChatsAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/groupchats/GroupChatsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/groupchats/GroupChatsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => communities}/groupchats/IGroupChatsView.kt (89%) delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationaudios/IChatAttachmentAudiosView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationdocs/IChatAttachmentDocsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationlinks/IChatAttachmentLinksView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationposts/IChatAttachmentPostsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationvideos/IChatAttachmentVideoView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => docs}/absdocumentpreview/AbsDocumentPreviewActivity.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => docs}/absdocumentpreview/AbsDocumentPreviewFragment.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => docs}/absdocumentpreview/BaseDocumentPresenter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => docs}/absdocumentpreview/IBasicDocumentView.kt (86%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/feedbanned/FeedBannedFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/feedbanned/FeedBannedPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedcomments/INewsfeedCommentsView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedcomments/NewsfeedCommentsAdapter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedcomments/NewsfeedCommentsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedcomments/NewsfeedCommentsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedmentions/NewsfeedMentionsFragment.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feed}/newsfeedmentions/NewsfeedMentionsPresenter.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feedback}/feedbackvkofficial/FeedbackPhotosAdapter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feedback}/feedbackvkofficial/FeedbackVKOfficialAdapter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feedback}/feedbackvkofficial/FeedbackVKOfficialFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feedback}/feedbackvkofficial/FeedbackVKOfficialPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => feedback}/feedbackvkofficial/IFeedbackVKOfficialView.kt (87%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => messages/chat}/sheet/AbsPresenterBottomSheetFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => messages/chat}/sheet/AttachmentsBottomSheetAdapter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => messages/chat}/sheet/IMessageAttachmentsView.kt (90%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => messages/chat}/sheet/MessageAttachmentsFragment.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => messages/chat}/sheet/MessageAttachmentsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/ConversationFragmentFactory.kt (56%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/abschatattachments/AbsChatAttachmentsFragment.kt (94%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/abschatattachments/BaseChatAttachmentsPresenter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/abschatattachments/IBaseChatAttachmentsView.kt (86%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationaudios/ChatAttachmentAudioPresenter.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationaudios/ConversationAudiosFragment.kt (92%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationaudios/IChatAttachmentAudiosView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationdocs/ChatAttachmentDocsPresenter.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationdocs/ConversationDocsFragment.kt (90%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationdocs/IChatAttachmentDocsView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationlinks/ChatAttachmentLinksPresenter.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationlinks/ConversationLinksFragment.kt (80%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationlinks/IChatAttachmentLinksView.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationmultiattachments/AttachmentConversationType.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationmultiattachments/ConversationMultiAttachmentsFragment.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationmultiattachments/ConversationMultiAttachmentsPresenter.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationmultiattachments/IConversationMultiAttachmentsView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationphotos/ChatAttachmentPhotoPresenter.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationphotos/ConversationPhotosFragment.kt (94%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationphotos/IChatAttachmentPhotosView.kt (60%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationposts/ChatAttachmentPostsPresenter.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationposts/ConversationPostsFragment.kt (79%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationposts/IChatAttachmentPostsView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationvideos/ChatAttachmentVideoPresenter.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{conversation => messages/conversationattachments}/conversationvideos/ConversationVideosFragment.kt (90%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/messages/conversationattachments/conversationvideos/IChatAttachmentVideoView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/createphotoalbum/CreatePhotoAlbumFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/createphotoalbum/EditPhotoAlbumPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/createphotoalbum/IEditPhotoAlbumView.kt (82%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localimagealbums/ILocalPhotoAlbumsView.kt (86%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localimagealbums/LocalImageAlbumsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localimagealbums/LocalPhotoAlbumsAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localimagealbums/LocalPhotoAlbumsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localphotos/ILocalPhotosView.kt (90%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localphotos/LocalPhotosAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localphotos/LocalPhotosFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/localphotos/LocalPhotosPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/photoallcomment/IPhotoAllCommentView.kt (92%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/photoallcomment/PhotoAllCommentFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/photoallcomment/PhotoAllCommentPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotoalbums/IPhotoAlbumsView.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotoalbums/PhotoAlbumsPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotoalbums/VKPhotoAlbumsAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotoalbums/VKPhotoAlbumsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotos/BigVKPhotosAdapter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotos/IVKPhotosView.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotos/VKPhotosFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => photos}/vkphotos/VKPhotosPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/createpin/CreatePinFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/createpin/CreatePinPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/createpin/ICreatePinView.kt (88%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/enterpin/EnterPinFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/enterpin/EnterPinPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => pin}/enterpin/IEnterPinView.kt (89%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/poll/createpoll/CreatePollDialogFragment.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => poll}/createpoll/CreatePollFragment.kt (72%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => poll}/createpoll/CreatePollPresenter.kt (66%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/poll/createpoll/HorizontalPollBackgroundAdapter.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => poll}/createpoll/ICreatePollView.kt (71%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => poll}/voters/VotersFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => poll}/voters/VotersPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/marketview/IMarketViewView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/marketview/MarketViewFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/marketview/MarketViewPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/productalbums/IProductAlbumsView.kt (88%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/productalbums/MarketAlbumAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/productalbums/ProductAlbumsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => products}/productalbums/ProductAlbumsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/localvideos/ILocalVideosView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/localvideos/LocalVideosAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/localvideos/LocalVideosFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/localvideos/LocalVideosPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbums/IVideoAlbumsView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbums/VideoAlbumsFragment.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbums/VideoAlbumsNewAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbums/VideoAlbumsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbumsbyvideo/IVideoAlbumsByVideoView.kt (88%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbumsbyvideo/VideoAlbumsByVideoFragment.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videoalbumsbyvideo/VideoAlbumsByVideoPresenter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videopreview/IVideoPreviewView.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videopreview/MenuAdapter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videopreview/VideoPreviewFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => videos}/videopreview/VideoPreviewPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{abswall => wall}/AbsWallFragment.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{abswall => wall}/AbsWallPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{abswall => wall}/IWallView.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{abswall => wall}/WallAdapter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/groupwall/GroupWallFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/groupwall/GroupWallPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/groupwall/IGroupWallView.kt (95%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userdetails/IUserDetailsView.kt (93%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userdetails/UserDetailsFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userdetails/UserDetailsPresenter.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userwall/IUserWallView.kt (94%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userwall/UserWallFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/userwall/UserWallPresenter.kt (99%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wall/wallattachments/WallAttachmentsFragmentFactory.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wall/wallattachments/wallmultiattachments/AttachmentWallType.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wall/wallattachments/wallmultiattachments/IWallMultiAttachmentsView.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{wallattachments/walllinksattachments => wall/wallattachments/wallmultiattachments}/LinksAdapter.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{wallattachments/wallphotoalbumattachments => wall/wallattachments/wallmultiattachments}/PhotoAlbumsAdapter.kt (97%) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wall/wallattachments/wallmultiattachments/WallMultiAttachmentsFragment.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wall/wallattachments/wallmultiattachments/WallMultiAttachmentsPresenter.kt rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallpostqueryattachments/IWallPostQueryAttachmentsView.kt (88%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallpostqueryattachments/WallPostQueryAttachmentsFragment.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallpostqueryattachments/WallPostQueryAttachmentsPresenter.kt (98%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallsearchcommentsattachments/IWallSearchCommentsAttachmentsView.kt (89%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallsearchcommentsattachments/WallSearchCommentsAttachmentsFragment.kt (91%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallattachments/wallsearchcommentsattachments/WallSearchCommentsAttachmentsPresenter.kt (96%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallpost/IWallPostView.kt (97%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallpost/WallPostFragment.kt (99%) rename app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/{ => wall}/wallpost/WallPostPresenter.kt (99%) delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/WallAttachmentsFragmentFactory.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallaudiosattachments/IWallAudiosAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallaudiosattachments/WallAudiosAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallaudiosattachments/WallAudiosAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walldocsattachments/IWallDocsAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walldocsattachments/WallDocsAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walldocsattachments/WallDocsAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walllinksattachments/IWallLinksAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walllinksattachments/WallLinksAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/walllinksattachments/WallLinksAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotoalbumattachments/IWallPhotoAlbumAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotoalbumattachments/WallPhotoAlbumAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotoalbumattachments/WallPhotoAlbumAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotosattachments/IWallPhotosAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotosattachments/WallPhotosAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallphotosattachments/WallPhotosAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallpostcommentattachments/IWallPostCommentAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallpostcommentattachments/WallPostCommentAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallpostcommentattachments/WallPostCommentAttachmentsPresenter.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallvideosattachments/IWallVideosAttachmentsView.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallvideosattachments/WallVideosAttachmentsFragment.kt delete mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/wallattachments/wallvideosattachments/WallVideosAttachmentsPresenter.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/FormatLanguage.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/PollGradientDrawable.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RecyclerViewSavedScroll.kt create mode 100644 app_fenrir/src/main/res/layout/fragment_create_poll_dialog.xml rename app_fenrir/src/main/res/layout/{fragment_wall_attachments_post_comment.xml => fragment_wall_conversation_attachments_multi.xml} (68%) create mode 100644 app_fenrir/src/main/res/layout/item_poll_background.xml create mode 100644 app_fenrir/src/main/res/layout/item_wall_attachments_recycler.xml rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/createpin/CreatePinFragment.kt (98%) rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/createpin/CreatePinPresenter.kt (99%) rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/createpin/ICreatePinView.kt (87%) rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/enterpin/EnterPinFragment.kt (98%) rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/enterpin/EnterPinPresenter.kt (98%) rename app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/{ => pin}/enterpin/IEnterPinView.kt (87%) create mode 100644 app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/FormatLanguage.kt create mode 100644 libfenrir/src/main/jni/audio/opus/libopus/silk/meson.build delete mode 100644 libfenrir/src/main/jni/audio/opus/libopus/silk/mips/NSQ_del_dec_mipsr1.h delete mode 100644 libfenrir/src/main/jni/audio/opus/libopus/silk/mips/macros_mipsr1.h delete mode 100644 libfenrir/src/main/jni/audio/opus/libopus/silk/mips/sigproc_fix_mipsr1.h delete mode 100644 libfenrir/src/main/jni/audio/opus/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/Extra.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/Extra.kt index 241bfcfb5..a93a279d9 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/Extra.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/Extra.kt @@ -47,6 +47,8 @@ object Extra { const val INDEX = "index" const val INVERT = "invert" const val IS_BOARD = "is_board" + const val IS_CHAT = "is_chat" + const val IS_EDIT = "is_edit" const val IS_OUT_OF_MEMORY = "is_out_of_memory" const val ITEM_ID = "item_id" const val KEY = "key" @@ -60,12 +62,12 @@ object Extra { const val MESSAGE_ID = "message_id" const val METHOD = "method" const val NEW = "new" + const val NO_OWNER_ID = "no_owner_id" const val OLD = "old" const val OUTGOING = "outgoing" const val OWNER = "owner" const val OWNERS = "owners" const val OWNER_ID = "owner_id" - const val NO_OWNER_ID = "no_owner_id" const val PASSWORD = "password" const val PATH = "path" const val PEER = "peer" diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/FcmListenerService.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/FcmListenerService.kt index 675633fd8..ed299d930 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/FcmListenerService.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/FcmListenerService.kt @@ -76,7 +76,7 @@ class FcmListenerService : FirebaseMessagingService() { .notify(accountId) PushType.POST -> WallPostFCMMessage.fromRemoteMessage(message) - ?.nofify(context, accountId) + ?.notify(context, accountId) PushType.COMMENT -> CommentFCMMessage.fromRemoteMessage(message) ?.notify(context, accountId) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/CreatePinActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/CreatePinActivity.kt index 2a310da71..e60b9b4c3 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/CreatePinActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/CreatePinActivity.kt @@ -2,7 +2,7 @@ package dev.ragnarok.fenrir.activity import android.os.Bundle import dev.ragnarok.fenrir.R -import dev.ragnarok.fenrir.fragment.createpin.CreatePinFragment +import dev.ragnarok.fenrir.fragment.pin.createpin.CreatePinFragment class CreatePinActivity : NoMainActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DualTabPhotoActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DualTabPhotoActivity.kt index c20a6ff5a..8b556ed6c 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DualTabPhotoActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DualTabPhotoActivity.kt @@ -6,9 +6,9 @@ import android.os.Bundle import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.fragment.DualTabPhotosFragment -import dev.ragnarok.fenrir.fragment.localphotos.LocalPhotosFragment -import dev.ragnarok.fenrir.fragment.vkphotos.IVKPhotosView -import dev.ragnarok.fenrir.fragment.vkphotos.VKPhotosFragment +import dev.ragnarok.fenrir.fragment.photos.localphotos.LocalPhotosFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotos.IVKPhotosView +import dev.ragnarok.fenrir.fragment.photos.vkphotos.VKPhotosFragment import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.getParcelableExtraCompat import dev.ragnarok.fenrir.model.LocalImageAlbum diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/EnterPinActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/EnterPinActivity.kt index 215ab5532..f9683ff31 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/EnterPinActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/EnterPinActivity.kt @@ -3,7 +3,7 @@ package dev.ragnarok.fenrir.activity import android.content.Context import android.os.Bundle import dev.ragnarok.fenrir.R -import dev.ragnarok.fenrir.fragment.enterpin.EnterPinFragment +import dev.ragnarok.fenrir.fragment.pin.enterpin.EnterPinFragment import dev.ragnarok.fenrir.util.Utils open class EnterPinActivity : NoMainActivity() { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt index 6ebe6828c..5f8a90c78 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt @@ -48,7 +48,6 @@ import dev.ragnarok.fenrir.domain.InteractorFactory import dev.ragnarok.fenrir.domain.impl.CountersInteractor import dev.ragnarok.fenrir.fragment.* import dev.ragnarok.fenrir.fragment.PreferencesFragment.Companion.cleanCache -import dev.ragnarok.fenrir.fragment.abswall.AbsWallFragment import dev.ragnarok.fenrir.fragment.attachments.commentcreate.CommentCreateFragment import dev.ragnarok.fenrir.fragment.attachments.commentedit.CommentEditFragment import dev.ragnarok.fenrir.fragment.attachments.postcreate.PostCreateFragment @@ -64,37 +63,35 @@ import dev.ragnarok.fenrir.fragment.audio.catalog_v2.lists.CatalogV2ListFragment import dev.ragnarok.fenrir.fragment.audio.catalog_v2.sections.CatalogV2SectionFragment import dev.ragnarok.fenrir.fragment.comments.CommentsFragment import dev.ragnarok.fenrir.fragment.communities.CommunitiesFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.CommunityControlFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communityban.CommunityBanEditFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communityinfocontacts.CommunityInfoContactsFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communityinfolinks.CommunityInfoLinksFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communitymanageredit.CommunityManagerEditFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communitymembers.CommunityMembersFragment -import dev.ragnarok.fenrir.fragment.conversation.ConversationFragmentFactory -import dev.ragnarok.fenrir.fragment.createphotoalbum.CreatePhotoAlbumFragment -import dev.ragnarok.fenrir.fragment.createpin.CreatePinFragment -import dev.ragnarok.fenrir.fragment.createpoll.CreatePollFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.CommunityControlFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban.CommunityBanEditFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfocontacts.CommunityInfoContactsFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfolinks.CommunityInfoLinksFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanageredit.CommunityManagerEditFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymembers.CommunityMembersFragment +import dev.ragnarok.fenrir.fragment.communities.groupchats.GroupChatsFragment import dev.ragnarok.fenrir.fragment.docs.DocsFragment import dev.ragnarok.fenrir.fragment.docs.DocsListPresenter import dev.ragnarok.fenrir.fragment.fave.FaveTabsFragment import dev.ragnarok.fenrir.fragment.feed.FeedFragment +import dev.ragnarok.fenrir.fragment.feed.feedbanned.FeedBannedFragment +import dev.ragnarok.fenrir.fragment.feed.newsfeedcomments.NewsfeedCommentsFragment +import dev.ragnarok.fenrir.fragment.feed.newsfeedmentions.NewsfeedMentionsFragment import dev.ragnarok.fenrir.fragment.feedback.FeedbackFragment -import dev.ragnarok.fenrir.fragment.feedbackvkofficial.FeedbackVKOfficialFragment -import dev.ragnarok.fenrir.fragment.feedbanned.FeedBannedFragment +import dev.ragnarok.fenrir.fragment.feedback.feedbackvkofficial.FeedbackVKOfficialFragment import dev.ragnarok.fenrir.fragment.friends.birthday.BirthDayFragment import dev.ragnarok.fenrir.fragment.friends.friendsbyphones.FriendsByPhonesFragment import dev.ragnarok.fenrir.fragment.friends.friendstabs.FriendsTabsFragment import dev.ragnarok.fenrir.fragment.gifts.GiftsFragment -import dev.ragnarok.fenrir.fragment.groupchats.GroupChatsFragment import dev.ragnarok.fenrir.fragment.likes.LikesFragment import dev.ragnarok.fenrir.fragment.likes.storiesview.StoriesViewFragment import dev.ragnarok.fenrir.fragment.localserver.filemanagerremote.FileManagerRemoteFragment import dev.ragnarok.fenrir.fragment.localserver.photoslocalserver.PhotosLocalServerFragment import dev.ragnarok.fenrir.fragment.logs.LogsFragment -import dev.ragnarok.fenrir.fragment.marketview.MarketViewFragment import dev.ragnarok.fenrir.fragment.messages.chat.ChatFragment import dev.ragnarok.fenrir.fragment.messages.chat.ChatFragment.Companion.newInstance import dev.ragnarok.fenrir.fragment.messages.chatmembers.ChatMembersFragment +import dev.ragnarok.fenrir.fragment.messages.conversationattachments.ConversationFragmentFactory import dev.ragnarok.fenrir.fragment.messages.dialogs.DialogsFragment import dev.ragnarok.fenrir.fragment.messages.fwds.FwdsFragment import dev.ragnarok.fenrir.fragment.messages.importantmessages.ImportantMessagesFragment @@ -103,13 +100,19 @@ import dev.ragnarok.fenrir.fragment.messages.notreadmessages.NotReadMessagesFrag import dev.ragnarok.fenrir.fragment.narratives.NarrativesFragment import dev.ragnarok.fenrir.fragment.navigationedit.DrawerEditFragment import dev.ragnarok.fenrir.fragment.navigationedit.SideDrawerEditFragment -import dev.ragnarok.fenrir.fragment.newsfeedcomments.NewsfeedCommentsFragment -import dev.ragnarok.fenrir.fragment.newsfeedmentions.NewsfeedMentionsFragment import dev.ragnarok.fenrir.fragment.ownerarticles.OwnerArticlesFragment -import dev.ragnarok.fenrir.fragment.photoallcomment.PhotoAllCommentFragment +import dev.ragnarok.fenrir.fragment.photos.createphotoalbum.CreatePhotoAlbumFragment +import dev.ragnarok.fenrir.fragment.photos.photoallcomment.PhotoAllCommentFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotoalbums.VKPhotoAlbumsFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotos.IVKPhotosView +import dev.ragnarok.fenrir.fragment.photos.vkphotos.VKPhotosFragment +import dev.ragnarok.fenrir.fragment.pin.createpin.CreatePinFragment import dev.ragnarok.fenrir.fragment.poll.PollFragment -import dev.ragnarok.fenrir.fragment.productalbums.ProductAlbumsFragment +import dev.ragnarok.fenrir.fragment.poll.createpoll.CreatePollFragment +import dev.ragnarok.fenrir.fragment.poll.voters.VotersFragment import dev.ragnarok.fenrir.fragment.products.ProductsFragment +import dev.ragnarok.fenrir.fragment.products.marketview.MarketViewFragment +import dev.ragnarok.fenrir.fragment.products.productalbums.ProductAlbumsFragment import dev.ragnarok.fenrir.fragment.requestexecute.RequestExecuteFragment import dev.ragnarok.fenrir.fragment.search.AudioSearchTabsFragment import dev.ragnarok.fenrir.fragment.search.SearchTabsFragment @@ -119,19 +122,16 @@ import dev.ragnarok.fenrir.fragment.shortedlinks.ShortedLinksFragment import dev.ragnarok.fenrir.fragment.theme.ThemeFragment import dev.ragnarok.fenrir.fragment.topics.TopicsFragment import dev.ragnarok.fenrir.fragment.userbanned.UserBannedFragment -import dev.ragnarok.fenrir.fragment.userdetails.UserDetailsFragment.Companion.newInstance -import dev.ragnarok.fenrir.fragment.videoalbumsbyvideo.VideoAlbumsByVideoFragment -import dev.ragnarok.fenrir.fragment.videopreview.VideoPreviewFragment import dev.ragnarok.fenrir.fragment.videos.IVideosListView import dev.ragnarok.fenrir.fragment.videos.VideosFragment import dev.ragnarok.fenrir.fragment.videos.VideosTabsFragment -import dev.ragnarok.fenrir.fragment.vkphotoalbums.VKPhotoAlbumsFragment -import dev.ragnarok.fenrir.fragment.vkphotos.IVKPhotosView -import dev.ragnarok.fenrir.fragment.vkphotos.VKPhotosFragment -import dev.ragnarok.fenrir.fragment.voters.VotersFragment -import dev.ragnarok.fenrir.fragment.wallattachments.WallAttachmentsFragmentFactory -import dev.ragnarok.fenrir.fragment.wallattachments.wallsearchcommentsattachments.WallSearchCommentsAttachmentsFragment -import dev.ragnarok.fenrir.fragment.wallpost.WallPostFragment +import dev.ragnarok.fenrir.fragment.videos.videoalbumsbyvideo.VideoAlbumsByVideoFragment +import dev.ragnarok.fenrir.fragment.videos.videopreview.VideoPreviewFragment +import dev.ragnarok.fenrir.fragment.wall.AbsWallFragment +import dev.ragnarok.fenrir.fragment.wall.userdetails.UserDetailsFragment.Companion.newInstance +import dev.ragnarok.fenrir.fragment.wall.wallattachments.WallAttachmentsFragmentFactory +import dev.ragnarok.fenrir.fragment.wall.wallattachments.wallsearchcommentsattachments.WallSearchCommentsAttachmentsFragment +import dev.ragnarok.fenrir.fragment.wall.wallpost.WallPostFragment import dev.ragnarok.fenrir.link.LinkHelper import dev.ragnarok.fenrir.listener.* import dev.ragnarok.fenrir.media.music.MusicPlaybackController @@ -1404,11 +1404,8 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect Place.EDIT_COMMENT -> { val comment: Comment? = args.getParcelableCompat(Extra.COMMENT) val accountId = args.getLong(Extra.ACCOUNT_ID) - val commemtId = args.getInt(Extra.COMMENT_ID) - val commentEditFragment = - CommentEditFragment.newInstance(accountId, comment, commemtId) - place.applyFragmentListener(commentEditFragment, supportFragmentManager) - attachToFront(commentEditFragment) + val commentId = args.getInt(Extra.COMMENT_ID) + attachToFront(CommentEditFragment.newInstance(accountId, comment, commentId)) } Place.EDIT_POST -> { @@ -1570,9 +1567,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect Place.UNREAD_MESSAGES -> attachToFront(NotReadMessagesFragment.newInstance(args)) Place.SECURITY -> attachToFront(SecurityPreferencesFragment()) Place.CREATE_POLL -> { - val createPollFragment = CreatePollFragment.newInstance(args) - place.applyFragmentListener(createPollFragment, supportFragmentManager) - attachToFront(createPollFragment) + attachToFront(CreatePollFragment.newInstance(args)) } Place.COMMENT_CREATE -> openCommentCreatePlace(place) @@ -1764,7 +1759,6 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect args.getLong(Extra.OWNER_ID), args.getString(Extra.BODY) ) - place.applyFragmentListener(fragment, supportFragmentManager) attachToFront(fragment) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotoAlbumsActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotoAlbumsActivity.kt index 73f2594df..b18f2be54 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotoAlbumsActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotoAlbumsActivity.kt @@ -3,8 +3,8 @@ package dev.ragnarok.fenrir.activity import android.os.Bundle import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R -import dev.ragnarok.fenrir.fragment.vkphotoalbums.VKPhotoAlbumsFragment -import dev.ragnarok.fenrir.fragment.vkphotos.VKPhotosFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotoalbums.VKPhotoAlbumsFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotos.VKPhotosFragment import dev.ragnarok.fenrir.place.Place import dev.ragnarok.fenrir.place.PlaceProvider diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotosActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotosActivity.kt index fcce4f0cf..c6ff72b79 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotosActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/PhotosActivity.kt @@ -3,8 +3,8 @@ package dev.ragnarok.fenrir.activity import android.os.Bundle import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R -import dev.ragnarok.fenrir.fragment.localimagealbums.LocalImageAlbumsFragment -import dev.ragnarok.fenrir.fragment.localphotos.LocalPhotosFragment +import dev.ragnarok.fenrir.fragment.photos.localimagealbums.LocalImageAlbumsFragment +import dev.ragnarok.fenrir.fragment.photos.localphotos.LocalPhotosFragment import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.model.LocalImageAlbum import dev.ragnarok.fenrir.place.Place diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt index 7aa597591..c3d7df56b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt @@ -22,9 +22,9 @@ import dev.ragnarok.fenrir.activity.slidr.Slidr.attach import dev.ragnarok.fenrir.activity.slidr.model.SlidrConfig import dev.ragnarok.fenrir.activity.slidr.model.SlidrListener import dev.ragnarok.fenrir.activity.slidr.model.SlidrPosition -import dev.ragnarok.fenrir.fragment.absdocumentpreview.AbsDocumentPreviewActivity import dev.ragnarok.fenrir.fragment.audio.AudioPlayerFragment import dev.ragnarok.fenrir.fragment.base.core.IPresenterFactory +import dev.ragnarok.fenrir.fragment.docs.absdocumentpreview.AbsDocumentPreviewActivity import dev.ragnarok.fenrir.getParcelableArrayListCompat import dev.ragnarok.fenrir.listener.AppStyleable import dev.ragnarok.fenrir.model.Document diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerPresenter.kt index 4363ecbf8..0efa56172 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerPresenter.kt @@ -5,7 +5,7 @@ import android.os.Bundle import android.view.View import com.google.android.material.snackbar.BaseTransientBottomBar import dev.ragnarok.fenrir.R -import dev.ragnarok.fenrir.fragment.absdocumentpreview.BaseDocumentPresenter +import dev.ragnarok.fenrir.fragment.docs.absdocumentpreview.BaseDocumentPresenter import dev.ragnarok.fenrir.model.Document import dev.ragnarok.fenrir.util.AppPerms.hasReadWriteStoragePermission import dev.ragnarok.fenrir.util.DownloadWorkUtils.doDownloadDoc diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/IGifPagerView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/IGifPagerView.kt index ab3bdf43c..9ffda022a 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/IGifPagerView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/IGifPagerView.kt @@ -1,7 +1,7 @@ package dev.ragnarok.fenrir.activity.gifpager import androidx.annotation.StringRes -import dev.ragnarok.fenrir.fragment.absdocumentpreview.IBasicDocumentView +import dev.ragnarok.fenrir.fragment.docs.absdocumentpreview.IBasicDocumentView import dev.ragnarok.fenrir.model.Document interface IGifPagerView : IBasicDocumentView { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/impl/PollsApi.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/impl/PollsApi.kt index 367b2695d..b18aeec19 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/impl/PollsApi.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/impl/PollsApi.kt @@ -19,6 +19,8 @@ internal class PollsApi(accountId: Long, provider: IServiceProvider) : question: String?, isAnonymous: Boolean?, isMultiple: Boolean?, + disableUnvote: Boolean, + backgroundId: Int?, ownerId: Long, addAnswers: List ): Single { @@ -29,6 +31,8 @@ internal class PollsApi(accountId: Long, provider: IServiceProvider) : question, integerFromBoolean(isAnonymous), integerFromBoolean(isMultiple), + integerFromBoolean(disableUnvote), + backgroundId, ownerId, Json.encodeToString(ListSerializer(String.serializer()), addAnswers) ) @@ -72,6 +76,14 @@ internal class PollsApi(accountId: Long, provider: IServiceProvider) : } } + override fun getBackgrounds(): Single> { + return provideService(IPollsService(), TokenType.USER) + .flatMap { service -> + service.getBackgrounds() + .map(extractResponseWithErrorHandling()) + } + } + override fun getVoters( ownerId: Long, pollId: Int, diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/interfaces/IPollsApi.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/interfaces/IPollsApi.kt index 8991e1f0a..1c4e769bd 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/interfaces/IPollsApi.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/interfaces/IPollsApi.kt @@ -11,6 +11,8 @@ interface IPollsApi { question: String?, isAnonymous: Boolean?, isMultiple: Boolean?, + disableUnvote: Boolean, + backgroundId: Int?, ownerId: Long, addAnswers: List ): Single @@ -37,4 +39,7 @@ interface IPollsApi { answer_ids: List, offset: Int?, count: Int? ): Single> + + @CheckResult + fun getBackgrounds(): Single> } \ No newline at end of file diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiPoll.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiPoll.kt index 1437bf42b..2c07ec558 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiPoll.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiPoll.kt @@ -64,6 +64,7 @@ class VKApiPoll var end_date: Long = 0 var multiple = false var photo: Photo? = null + var background: Background? = null override fun getType(): String { return VKApiAttachment.TYPE_POLL } @@ -94,6 +95,21 @@ class VKApiPoll var rate = 0.0 } + @Serializable + class Background { + var type: String? = null + var id = 0 + var angle = 0 + var name: String? = null + var points: List? = null + } + + @Serializable + class BackgroundPoint { + var color: String? = null + var position = 0.0f + } + @Serializable class Photo { var color: String? = null diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/services/IPollsService.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/services/IPollsService.kt index 4c6725e66..e925d7899 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/services/IPollsService.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/services/IPollsService.kt @@ -11,6 +11,8 @@ class IPollsService : IServiceRest() { question: String?, isAnonymous: Int?, isMultiple: Int?, + disableUnvote: Int?, + backgroundId: Int?, ownerId: Long?, addAnswers: String? ): Single> { @@ -19,6 +21,8 @@ class IPollsService : IServiceRest() { "question" to question, "is_anonymous" to isAnonymous, "is_multiple" to isMultiple, + "disable_unvote" to disableUnvote, + "background_id" to backgroundId, "owner_id" to ownerId, "add_answers" to addAnswers ), base(VKApiPoll.serializer()) @@ -96,4 +100,10 @@ class IPollsService : IServiceRest() { ), baseList(PollUsersResponse.serializer()) ) } + + fun getBackgrounds(): Single>> { + return rest.request( + "polls.getBackgrounds", null, baseList(VKApiPoll.Background.serializer()) + ) + } } \ No newline at end of file diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/PollDboEntity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/PollDboEntity.kt index d749e38b2..eb6a6c81c 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/PollDboEntity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/PollDboEntity.kt @@ -1,5 +1,6 @@ package dev.ragnarok.fenrir.db.model.entity +import androidx.annotation.ColorInt import androidx.annotation.Keep import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -36,6 +37,8 @@ class PollDboEntity : DboEntity() { private set var photo: String? = null private set + var background: BackgroundEntity? = null + private set operator fun set(id: Int, ownerId: Long): PollDboEntity { this.id = id @@ -98,6 +101,11 @@ class PollDboEntity : DboEntity() { return this } + fun setBackground(background: BackgroundEntity?): PollDboEntity { + this.background = background + return this + } + fun setVoteCount(voteCount: Int): PollDboEntity { this.voteCount = voteCount return this @@ -123,6 +131,19 @@ class PollDboEntity : DboEntity() { return this } + @Keep + @Serializable + class BackgroundEntity( + var id: Int, + var angle: Int, + var name: String?, + var points: List + ) + + @Keep + @Serializable + class BackgroundPointEntity(@ColorInt var color: Int, var position: Float) + @Keep @Serializable class Answer { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/dialog/PostShareDialog.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/dialog/PostShareDialog.kt index c174bf38e..826297695 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/dialog/PostShareDialog.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/dialog/PostShareDialog.kt @@ -8,7 +8,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.domain.Repository.owners -import dev.ragnarok.fenrir.fragment.videopreview.MenuAdapter +import dev.ragnarok.fenrir.fragment.videos.videopreview.MenuAdapter import dev.ragnarok.fenrir.fromIOToMain import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.model.Post diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/IPollInteractor.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/IPollInteractor.kt index 123f5ad74..cf57dc26b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/IPollInteractor.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/IPollInteractor.kt @@ -10,6 +10,8 @@ interface IPollInteractor { question: String?, anon: Boolean, multiple: Boolean, + disableUnvote: Boolean, + backgroundId: Int?, ownerId: Long, options: List ): Single @@ -26,4 +28,6 @@ interface IPollInteractor { offset: Int?, count: Int? ): Single> + + fun getBackgrounds(accountId: Long): Single> } \ No newline at end of file diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/impl/PollInteractor.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/impl/PollInteractor.kt index ae34c27b6..1b76cc684 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/impl/PollInteractor.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/impl/PollInteractor.kt @@ -2,6 +2,7 @@ package dev.ragnarok.fenrir.domain.impl import dev.ragnarok.fenrir.api.interfaces.INetworker import dev.ragnarok.fenrir.domain.IPollInteractor +import dev.ragnarok.fenrir.domain.mappers.Dto2Model import dev.ragnarok.fenrir.domain.mappers.Dto2Model.transform import dev.ragnarok.fenrir.domain.mappers.Dto2Model.transformUsers import dev.ragnarok.fenrir.model.Poll @@ -14,12 +15,14 @@ class PollInteractor(private val networker: INetworker) : IPollInteractor { question: String?, anon: Boolean, multiple: Boolean, + disableUnvote: Boolean, + backgroundId: Int?, ownerId: Long, options: List ): Single { return networker.vkDefault(accountId) .polls() - .create(question, anon, multiple, ownerId, options) + .create(question, anon, multiple, disableUnvote, backgroundId, ownerId, options) .map { transform(it) } } @@ -51,6 +54,23 @@ class PollInteractor(private val networker: INetworker) : IPollInteractor { } } + override fun getBackgrounds(accountId: Long): Single> { + return networker.vkDefault(accountId) + .polls() + .getBackgrounds() + .flatMap { + val tmpList = ArrayList(it.size + 1) + tmpList.add(Poll.PollBackground(-1).setName("default")) + for (i in it) { + val s = Dto2Model.buildPollBackgroundGradient(i) + if (s != null) { + tmpList.add(s) + } + } + Single.just(tmpList) + } + } + override fun getPollById( accountId: Long, ownerId: Long, diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Entity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Entity.kt index f914e9273..cdeb6f7b6 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Entity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Entity.kt @@ -1,10 +1,62 @@ package dev.ragnarok.fenrir.domain.mappers -import dev.ragnarok.fenrir.api.model.* +import android.graphics.Color +import dev.ragnarok.fenrir.api.model.PhotoSizeDto +import dev.ragnarok.fenrir.api.model.VKApiArticle +import dev.ragnarok.fenrir.api.model.VKApiAttachments +import dev.ragnarok.fenrir.api.model.VKApiAudio +import dev.ragnarok.fenrir.api.model.VKApiAudioArtist +import dev.ragnarok.fenrir.api.model.VKApiAudioMessage +import dev.ragnarok.fenrir.api.model.VKApiAudioPlaylist +import dev.ragnarok.fenrir.api.model.VKApiCall +import dev.ragnarok.fenrir.api.model.VKApiCareer +import dev.ragnarok.fenrir.api.model.VKApiCity +import dev.ragnarok.fenrir.api.model.VKApiComment +import dev.ragnarok.fenrir.api.model.VKApiCommunity +import dev.ragnarok.fenrir.api.model.VKApiConversation import dev.ragnarok.fenrir.api.model.VKApiConversation.CurrentKeyboard +import dev.ragnarok.fenrir.api.model.VKApiCountry +import dev.ragnarok.fenrir.api.model.VKApiDialog +import dev.ragnarok.fenrir.api.model.VKApiDoc +import dev.ragnarok.fenrir.api.model.VKApiEvent +import dev.ragnarok.fenrir.api.model.VKApiGeo +import dev.ragnarok.fenrir.api.model.VKApiGiftItem +import dev.ragnarok.fenrir.api.model.VKApiGraffiti +import dev.ragnarok.fenrir.api.model.VKApiLink +import dev.ragnarok.fenrir.api.model.VKApiMarket +import dev.ragnarok.fenrir.api.model.VKApiMarketAlbum +import dev.ragnarok.fenrir.api.model.VKApiMessage +import dev.ragnarok.fenrir.api.model.VKApiMilitary +import dev.ragnarok.fenrir.api.model.VKApiNews +import dev.ragnarok.fenrir.api.model.VKApiNotSupported +import dev.ragnarok.fenrir.api.model.VKApiPhoto +import dev.ragnarok.fenrir.api.model.VKApiPhotoAlbum +import dev.ragnarok.fenrir.api.model.VKApiPoll +import dev.ragnarok.fenrir.api.model.VKApiPost +import dev.ragnarok.fenrir.api.model.VKApiPrivacy +import dev.ragnarok.fenrir.api.model.VKApiSchool +import dev.ragnarok.fenrir.api.model.VKApiSticker import dev.ragnarok.fenrir.api.model.VKApiSticker.VKApiAnimation +import dev.ragnarok.fenrir.api.model.VKApiStickerSet import dev.ragnarok.fenrir.api.model.VKApiStickerSet.Product -import dev.ragnarok.fenrir.api.model.feedback.* +import dev.ragnarok.fenrir.api.model.VKApiStory +import dev.ragnarok.fenrir.api.model.VKApiTopic +import dev.ragnarok.fenrir.api.model.VKApiUniversity +import dev.ragnarok.fenrir.api.model.VKApiUser +import dev.ragnarok.fenrir.api.model.VKApiVideo +import dev.ragnarok.fenrir.api.model.VKApiVideoAlbum +import dev.ragnarok.fenrir.api.model.VKApiWallReply +import dev.ragnarok.fenrir.api.model.VKApiWikiPage +import dev.ragnarok.fenrir.api.model.feedback.VKApiBaseFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiCommentFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiCopyFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiLikeCommentFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiLikeFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiMentionCommentFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiMentionWallFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiReplyCommentFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiUsersFeedback +import dev.ragnarok.fenrir.api.model.feedback.VKApiWallFeedback import dev.ragnarok.fenrir.api.model.interfaces.Commentable import dev.ragnarok.fenrir.api.model.interfaces.Likeable import dev.ragnarok.fenrir.api.model.interfaces.VKApiAttachment @@ -12,15 +64,72 @@ import dev.ragnarok.fenrir.api.model.response.FavePageResponse import dev.ragnarok.fenrir.crypt.CryptHelper.analizeMessageBody import dev.ragnarok.fenrir.crypt.MessageType import dev.ragnarok.fenrir.db.model.IdPairEntity -import dev.ragnarok.fenrir.db.model.entity.* +import dev.ragnarok.fenrir.db.model.entity.ArticleDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioArtistDboEntity import dev.ragnarok.fenrir.db.model.entity.AudioArtistDboEntity.AudioArtistImageEntity +import dev.ragnarok.fenrir.db.model.entity.AudioDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioMessageDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioPlaylistDboEntity +import dev.ragnarok.fenrir.db.model.entity.CallDboEntity +import dev.ragnarok.fenrir.db.model.entity.CareerEntity +import dev.ragnarok.fenrir.db.model.entity.CityEntity +import dev.ragnarok.fenrir.db.model.entity.CommentEntity +import dev.ragnarok.fenrir.db.model.entity.CommunityDetailsEntity +import dev.ragnarok.fenrir.db.model.entity.CommunityEntity +import dev.ragnarok.fenrir.db.model.entity.CopiesEntity +import dev.ragnarok.fenrir.db.model.entity.CountryDboEntity +import dev.ragnarok.fenrir.db.model.entity.DboEntity +import dev.ragnarok.fenrir.db.model.entity.DialogDboEntity +import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity.GraffitiDbo import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity.VideoPreviewDbo +import dev.ragnarok.fenrir.db.model.entity.EventDboEntity +import dev.ragnarok.fenrir.db.model.entity.FavePageEntity +import dev.ragnarok.fenrir.db.model.entity.GeoDboEntity +import dev.ragnarok.fenrir.db.model.entity.GiftItemDboEntity +import dev.ragnarok.fenrir.db.model.entity.GraffitiDboEntity +import dev.ragnarok.fenrir.db.model.entity.KeyboardEntity import dev.ragnarok.fenrir.db.model.entity.KeyboardEntity.ButtonEntity +import dev.ragnarok.fenrir.db.model.entity.LinkDboEntity +import dev.ragnarok.fenrir.db.model.entity.MarketAlbumDboEntity +import dev.ragnarok.fenrir.db.model.entity.MarketDboEntity +import dev.ragnarok.fenrir.db.model.entity.MessageDboEntity +import dev.ragnarok.fenrir.db.model.entity.MilitaryEntity +import dev.ragnarok.fenrir.db.model.entity.NewsDboEntity +import dev.ragnarok.fenrir.db.model.entity.NotSupportedDboEntity +import dev.ragnarok.fenrir.db.model.entity.OwnerEntities +import dev.ragnarok.fenrir.db.model.entity.PageDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoAlbumDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoSizeEntity +import dev.ragnarok.fenrir.db.model.entity.PollDboEntity +import dev.ragnarok.fenrir.db.model.entity.PostDboEntity import dev.ragnarok.fenrir.db.model.entity.PostDboEntity.SourceDbo +import dev.ragnarok.fenrir.db.model.entity.PrivacyEntity +import dev.ragnarok.fenrir.db.model.entity.SchoolEntity +import dev.ragnarok.fenrir.db.model.entity.SimpleDialogEntity +import dev.ragnarok.fenrir.db.model.entity.StickerDboEntity import dev.ragnarok.fenrir.db.model.entity.StickerDboEntity.AnimationEntity +import dev.ragnarok.fenrir.db.model.entity.StickerSetEntity +import dev.ragnarok.fenrir.db.model.entity.StoryDboEntity +import dev.ragnarok.fenrir.db.model.entity.TopicDboEntity +import dev.ragnarok.fenrir.db.model.entity.UniversityEntity +import dev.ragnarok.fenrir.db.model.entity.UserDetailsEntity import dev.ragnarok.fenrir.db.model.entity.UserDetailsEntity.RelativeEntity -import dev.ragnarok.fenrir.db.model.entity.feedback.* +import dev.ragnarok.fenrir.db.model.entity.UserEntity +import dev.ragnarok.fenrir.db.model.entity.VideoAlbumDboEntity +import dev.ragnarok.fenrir.db.model.entity.VideoDboEntity +import dev.ragnarok.fenrir.db.model.entity.WallReplyDboEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.CopyEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.FeedbackEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.LikeCommentEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.LikeEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.MentionCommentEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.MentionEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.NewCommentEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.PostFeedbackEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.ReplyCommentEntity +import dev.ragnarok.fenrir.db.model.entity.feedback.UsersEntity import dev.ragnarok.fenrir.domain.mappers.MapUtil.calculateConversationAcl import dev.ragnarok.fenrir.domain.mappers.MapUtil.mapAll import dev.ragnarok.fenrir.model.CommentedType @@ -1026,6 +1135,36 @@ object Dto2Entity { return url } + private fun buildPollBackgroundGradient(background: VKApiPoll.Background?): PollDboEntity.BackgroundEntity? { + if (background == null || background.type != "gradient") { + return null + } + val list = ArrayList() + for (i in background.points.orEmpty()) { + if (i.color.nonNullNoEmpty()) { + try { + val pp = PollDboEntity.BackgroundPointEntity( + Color.parseColor("#" + i.color), + i.position + ) + list.add(pp) + } catch (e: Exception) { + e.printStackTrace() + continue + } + } + } + if (list.isEmpty()) { + return null + } + return PollDboEntity.BackgroundEntity( + background.id, + background.angle, + background.name, + list + ) + } + private fun buildPollEntity(dto: VKApiPoll): PollDboEntity { return PollDboEntity().set(dto.id, dto.owner_id) .setAnonymous(dto.anonymous) @@ -1050,6 +1189,7 @@ object Dto2Entity { .setEndDate(dto.end_date) .setMultiple(dto.multiple) .setPhoto(buildPollPhoto(dto.photo)) + .setBackground(buildPollBackgroundGradient(dto.background)) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Model.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Model.kt index eb0f0a4f8..ab0da5924 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Model.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Dto2Model.kt @@ -1,7 +1,51 @@ package dev.ragnarok.fenrir.domain.mappers -import dev.ragnarok.fenrir.api.model.* +import android.graphics.Color +import dev.ragnarok.fenrir.api.model.FaveLinkDto +import dev.ragnarok.fenrir.api.model.PhotoSizeDto +import dev.ragnarok.fenrir.api.model.VKApiArticle +import dev.ragnarok.fenrir.api.model.VKApiAttachments +import dev.ragnarok.fenrir.api.model.VKApiAudio +import dev.ragnarok.fenrir.api.model.VKApiAudioArtist +import dev.ragnarok.fenrir.api.model.VKApiAudioMessage +import dev.ragnarok.fenrir.api.model.VKApiAudioPlaylist +import dev.ragnarok.fenrir.api.model.VKApiCall +import dev.ragnarok.fenrir.api.model.VKApiChat +import dev.ragnarok.fenrir.api.model.VKApiComment +import dev.ragnarok.fenrir.api.model.VKApiCommunity +import dev.ragnarok.fenrir.api.model.VKApiConversation import dev.ragnarok.fenrir.api.model.VKApiConversation.CurrentKeyboard +import dev.ragnarok.fenrir.api.model.VKApiDialog +import dev.ragnarok.fenrir.api.model.VKApiDoc +import dev.ragnarok.fenrir.api.model.VKApiEvent +import dev.ragnarok.fenrir.api.model.VKApiFriendList +import dev.ragnarok.fenrir.api.model.VKApiGeo +import dev.ragnarok.fenrir.api.model.VKApiGift +import dev.ragnarok.fenrir.api.model.VKApiGiftItem +import dev.ragnarok.fenrir.api.model.VKApiGraffiti +import dev.ragnarok.fenrir.api.model.VKApiGroupChats +import dev.ragnarok.fenrir.api.model.VKApiLink +import dev.ragnarok.fenrir.api.model.VKApiMarket +import dev.ragnarok.fenrir.api.model.VKApiMarketAlbum +import dev.ragnarok.fenrir.api.model.VKApiMessage +import dev.ragnarok.fenrir.api.model.VKApiNarratives +import dev.ragnarok.fenrir.api.model.VKApiNews +import dev.ragnarok.fenrir.api.model.VKApiNotSupported +import dev.ragnarok.fenrir.api.model.VKApiOwner +import dev.ragnarok.fenrir.api.model.VKApiPhoto +import dev.ragnarok.fenrir.api.model.VKApiPhotoAlbum +import dev.ragnarok.fenrir.api.model.VKApiPhotoTags +import dev.ragnarok.fenrir.api.model.VKApiPoll +import dev.ragnarok.fenrir.api.model.VKApiPost +import dev.ragnarok.fenrir.api.model.VKApiPrivacy +import dev.ragnarok.fenrir.api.model.VKApiShortLink +import dev.ragnarok.fenrir.api.model.VKApiSticker +import dev.ragnarok.fenrir.api.model.VKApiStory +import dev.ragnarok.fenrir.api.model.VKApiTopic +import dev.ragnarok.fenrir.api.model.VKApiUser +import dev.ragnarok.fenrir.api.model.VKApiVideo +import dev.ragnarok.fenrir.api.model.VKApiWallReply +import dev.ragnarok.fenrir.api.model.VKApiWikiPage import dev.ragnarok.fenrir.api.model.interfaces.VKApiAttachment import dev.ragnarok.fenrir.api.model.longpoll.AddMessageUpdate import dev.ragnarok.fenrir.api.model.response.FavePageResponse @@ -11,9 +55,63 @@ import dev.ragnarok.fenrir.crypt.MessageType import dev.ragnarok.fenrir.db.model.entity.PostDboEntity import dev.ragnarok.fenrir.domain.mappers.MapUtil.calculateConversationAcl import dev.ragnarok.fenrir.domain.mappers.MapUtil.mapAll -import dev.ragnarok.fenrir.model.* +import dev.ragnarok.fenrir.model.Article +import dev.ragnarok.fenrir.model.Attachments +import dev.ragnarok.fenrir.model.Audio +import dev.ragnarok.fenrir.model.AudioArtist import dev.ragnarok.fenrir.model.AudioArtist.AudioArtistImage +import dev.ragnarok.fenrir.model.AudioPlaylist +import dev.ragnarok.fenrir.model.Call +import dev.ragnarok.fenrir.model.Chat +import dev.ragnarok.fenrir.model.Comment +import dev.ragnarok.fenrir.model.Commented +import dev.ragnarok.fenrir.model.Community +import dev.ragnarok.fenrir.model.Conversation +import dev.ragnarok.fenrir.model.CryptStatus +import dev.ragnarok.fenrir.model.Dialog +import dev.ragnarok.fenrir.model.Document import dev.ragnarok.fenrir.model.Document.VideoPreview +import dev.ragnarok.fenrir.model.Event +import dev.ragnarok.fenrir.model.FaveLink +import dev.ragnarok.fenrir.model.FavePage +import dev.ragnarok.fenrir.model.FavePageType +import dev.ragnarok.fenrir.model.FriendList +import dev.ragnarok.fenrir.model.Geo +import dev.ragnarok.fenrir.model.Gift +import dev.ragnarok.fenrir.model.GiftItem +import dev.ragnarok.fenrir.model.Graffiti +import dev.ragnarok.fenrir.model.GroupChats +import dev.ragnarok.fenrir.model.IOwnersBundle +import dev.ragnarok.fenrir.model.Keyboard +import dev.ragnarok.fenrir.model.Link +import dev.ragnarok.fenrir.model.Market +import dev.ragnarok.fenrir.model.MarketAlbum +import dev.ragnarok.fenrir.model.Message +import dev.ragnarok.fenrir.model.MessageStatus +import dev.ragnarok.fenrir.model.Narratives +import dev.ragnarok.fenrir.model.News +import dev.ragnarok.fenrir.model.NotSupported +import dev.ragnarok.fenrir.model.Owner +import dev.ragnarok.fenrir.model.OwnerType +import dev.ragnarok.fenrir.model.Peer +import dev.ragnarok.fenrir.model.Photo +import dev.ragnarok.fenrir.model.PhotoAlbum +import dev.ragnarok.fenrir.model.PhotoSizes +import dev.ragnarok.fenrir.model.PhotoTags +import dev.ragnarok.fenrir.model.Poll +import dev.ragnarok.fenrir.model.Post +import dev.ragnarok.fenrir.model.PostSource +import dev.ragnarok.fenrir.model.Privacy +import dev.ragnarok.fenrir.model.ShortLink +import dev.ragnarok.fenrir.model.SimplePrivacy +import dev.ragnarok.fenrir.model.Sticker +import dev.ragnarok.fenrir.model.Story +import dev.ragnarok.fenrir.model.Topic +import dev.ragnarok.fenrir.model.User +import dev.ragnarok.fenrir.model.Video +import dev.ragnarok.fenrir.model.VoiceMessage +import dev.ragnarok.fenrir.model.WallReply +import dev.ragnarok.fenrir.model.WikiPage import dev.ragnarok.fenrir.nonNullNoEmpty import dev.ragnarok.fenrir.orZero import dev.ragnarok.fenrir.requireNonNull @@ -657,6 +755,30 @@ object Dto2Model { return url } + fun buildPollBackgroundGradient(background: VKApiPoll.Background?): Poll.PollBackground? { + if (background == null || background.type != "gradient") { + return null + } + val list = ArrayList() + for (i in background.points.orEmpty()) { + if (i.color.nonNullNoEmpty()) { + try { + list.add( + Poll.PollBackgroundPoint().setColor(Color.parseColor("#" + i.color)) + .setPosition(i.position) + ) + } catch (e: Exception) { + e.printStackTrace() + continue + } + } + } + if (list.isEmpty()) { + return null + } + return Poll.PollBackground(background.id).setName(background.name) + .setAngle(background.angle).setPoints(list) + } fun transform(dto: VKApiPoll): Poll { val answers: MutableList = ArrayList(safeCountOf(dto.answers)) @@ -687,6 +809,7 @@ object Dto2Model { .setEndDate(dto.end_date) .setMultiple(dto.multiple) .setPhoto(buildPollPhoto(dto.photo)) + .setBackground(buildPollBackgroundGradient(dto.background)) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Entity2Model.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Entity2Model.kt index b94befef6..5444d351f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Entity2Model.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Entity2Model.kt @@ -824,6 +824,22 @@ object Entity2Model { .setVoteCount(entity.voteCount) } + fun map(entity: PollDboEntity.BackgroundPointEntity): Poll.PollBackgroundPoint { + return Poll.PollBackgroundPoint() + .setColor(entity.color) + .setPosition(entity.position) + } + + fun map(entity: PollDboEntity.BackgroundEntity?): Poll.PollBackground? { + if (entity == null) { + return null + } + return Poll.PollBackground(entity.id) + .setAngle(entity.angle) + .setName(entity.name) + .setPoints(mapAll(entity.points, Entity2Model::map)) + } + private fun buildPollFromDbo(entity: PollDboEntity): Poll { return Poll(entity.id, entity.ownerId) .setAnonymous(entity.isAnonymous) @@ -842,6 +858,7 @@ object Entity2Model { .setEndDate(entity.endDate) .setMultiple(entity.isMultiple) .setPhoto(entity.photo) + .setBackground(map(entity.background)) } private fun buildLinkFromDbo(dbo: LinkDboEntity): Link { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Model2Entity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Model2Entity.kt index c0396384c..e77dd3668 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Model2Entity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/mappers/Model2Entity.kt @@ -1,16 +1,77 @@ package dev.ragnarok.fenrir.domain.mappers -import dev.ragnarok.fenrir.db.model.entity.* +import dev.ragnarok.fenrir.db.model.entity.ArticleDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioArtistDboEntity import dev.ragnarok.fenrir.db.model.entity.AudioArtistDboEntity.AudioArtistImageEntity +import dev.ragnarok.fenrir.db.model.entity.AudioDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioMessageDboEntity +import dev.ragnarok.fenrir.db.model.entity.AudioPlaylistDboEntity +import dev.ragnarok.fenrir.db.model.entity.CallDboEntity +import dev.ragnarok.fenrir.db.model.entity.DboEntity +import dev.ragnarok.fenrir.db.model.entity.DialogDboEntity +import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity.GraffitiDbo import dev.ragnarok.fenrir.db.model.entity.DocumentDboEntity.VideoPreviewDbo +import dev.ragnarok.fenrir.db.model.entity.EventDboEntity +import dev.ragnarok.fenrir.db.model.entity.GeoDboEntity +import dev.ragnarok.fenrir.db.model.entity.GiftItemDboEntity +import dev.ragnarok.fenrir.db.model.entity.GraffitiDboEntity +import dev.ragnarok.fenrir.db.model.entity.KeyboardEntity import dev.ragnarok.fenrir.db.model.entity.KeyboardEntity.ButtonEntity +import dev.ragnarok.fenrir.db.model.entity.LinkDboEntity +import dev.ragnarok.fenrir.db.model.entity.MarketAlbumDboEntity +import dev.ragnarok.fenrir.db.model.entity.MarketDboEntity +import dev.ragnarok.fenrir.db.model.entity.MessageDboEntity +import dev.ragnarok.fenrir.db.model.entity.NotSupportedDboEntity +import dev.ragnarok.fenrir.db.model.entity.PageDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoAlbumDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoDboEntity +import dev.ragnarok.fenrir.db.model.entity.PhotoSizeEntity +import dev.ragnarok.fenrir.db.model.entity.PollDboEntity +import dev.ragnarok.fenrir.db.model.entity.PostDboEntity import dev.ragnarok.fenrir.db.model.entity.PostDboEntity.SourceDbo +import dev.ragnarok.fenrir.db.model.entity.PrivacyEntity +import dev.ragnarok.fenrir.db.model.entity.StickerDboEntity import dev.ragnarok.fenrir.db.model.entity.StickerDboEntity.AnimationEntity +import dev.ragnarok.fenrir.db.model.entity.StoryDboEntity +import dev.ragnarok.fenrir.db.model.entity.VideoDboEntity +import dev.ragnarok.fenrir.db.model.entity.WallReplyDboEntity import dev.ragnarok.fenrir.domain.mappers.MapUtil.mapAll import dev.ragnarok.fenrir.domain.mappers.MapUtil.mapAndAdd -import dev.ragnarok.fenrir.model.* +import dev.ragnarok.fenrir.model.AbsModel +import dev.ragnarok.fenrir.model.AbsModelType +import dev.ragnarok.fenrir.model.Article +import dev.ragnarok.fenrir.model.Attachments +import dev.ragnarok.fenrir.model.Audio +import dev.ragnarok.fenrir.model.AudioArtist import dev.ragnarok.fenrir.model.AudioArtist.AudioArtistImage +import dev.ragnarok.fenrir.model.AudioPlaylist +import dev.ragnarok.fenrir.model.Call +import dev.ragnarok.fenrir.model.CryptStatus +import dev.ragnarok.fenrir.model.Dialog +import dev.ragnarok.fenrir.model.Document +import dev.ragnarok.fenrir.model.Event +import dev.ragnarok.fenrir.model.Geo +import dev.ragnarok.fenrir.model.GiftItem +import dev.ragnarok.fenrir.model.Graffiti +import dev.ragnarok.fenrir.model.Keyboard +import dev.ragnarok.fenrir.model.Link +import dev.ragnarok.fenrir.model.Market +import dev.ragnarok.fenrir.model.MarketAlbum +import dev.ragnarok.fenrir.model.Message +import dev.ragnarok.fenrir.model.NotSupported +import dev.ragnarok.fenrir.model.Photo +import dev.ragnarok.fenrir.model.PhotoAlbum +import dev.ragnarok.fenrir.model.PhotoSizes +import dev.ragnarok.fenrir.model.Poll +import dev.ragnarok.fenrir.model.Post +import dev.ragnarok.fenrir.model.SimplePrivacy +import dev.ragnarok.fenrir.model.Sticker +import dev.ragnarok.fenrir.model.Story +import dev.ragnarok.fenrir.model.Video +import dev.ragnarok.fenrir.model.VoiceMessage +import dev.ragnarok.fenrir.model.WallReply +import dev.ragnarok.fenrir.model.WikiPage import dev.ragnarok.fenrir.orZero import dev.ragnarok.fenrir.requireNonNull @@ -339,6 +400,22 @@ object Model2Entity { return PollDboEntity.Answer().set(answer.id, answer.text, answer.voteCount, answer.rate) } + fun map(entity: Poll.PollBackgroundPoint): PollDboEntity.BackgroundPointEntity { + return PollDboEntity.BackgroundPointEntity(entity.color, entity.position) + } + + fun map(model: Poll.PollBackground?): PollDboEntity.BackgroundEntity? { + if (model == null) { + return null + } + return PollDboEntity.BackgroundEntity( + model.id, + model.angle, + model.name, + mapAll(model.points, Model2Entity::map) + ) + } + private fun buildPollDbo(poll: Poll): PollDboEntity { return PollDboEntity().set(poll.id, poll.ownerId) .setAnswers( @@ -361,6 +438,7 @@ object Model2Entity { .setEndDate(poll.endDate) .setMultiple(poll.isMultiple) .setPhoto(poll.photo) + .setBackground(map(poll.background)) } private fun buildLinkDbo(link: Link): LinkDboEntity { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt index 4b81895c6..bd01abff3 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt @@ -18,10 +18,10 @@ import dev.ragnarok.fenrir.activity.ActivityUtils.supportToolbarFor import dev.ragnarok.fenrir.fragment.base.BaseFragment import dev.ragnarok.fenrir.fragment.base.BaseMvpFragment import dev.ragnarok.fenrir.fragment.filemanagerselect.FileManagerSelectFragment -import dev.ragnarok.fenrir.fragment.localimagealbums.LocalImageAlbumsFragment -import dev.ragnarok.fenrir.fragment.localphotos.LocalPhotosFragment -import dev.ragnarok.fenrir.fragment.localvideos.LocalVideosFragment -import dev.ragnarok.fenrir.fragment.vkphotoalbums.VKPhotoAlbumsFragment +import dev.ragnarok.fenrir.fragment.photos.localimagealbums.LocalImageAlbumsFragment +import dev.ragnarok.fenrir.fragment.photos.localphotos.LocalPhotosFragment +import dev.ragnarok.fenrir.fragment.photos.vkphotoalbums.VKPhotoAlbumsFragment +import dev.ragnarok.fenrir.fragment.videos.localvideos.LocalVideosFragment import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.listener.BackPressCallback import dev.ragnarok.fenrir.model.selection.* diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/PreferencesFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/PreferencesFragment.kt index 2590e602b..baa76bfca 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/PreferencesFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/PreferencesFragment.kt @@ -1757,7 +1757,7 @@ class PreferencesFragment : AbsPreferencesFragment(), PreferencesAdapter.OnScree onClick { MaterialAlertDialogBuilder(requireActivity()).setIcon(R.drawable.ic_outline_delete) .setTitle(R.string.select) - .setMessage(R.string.do_delete) + .setMessage(R.string.ask_account_cache_cleaner) .setPositiveButton(R.string.button_yes) { _: DialogInterface?, _: Int -> DBHelper.removeDatabaseFor(requireActivity(), accountId) cleanCache(requireActivity(), true) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/SecurityPreferencesFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/SecurityPreferencesFragment.kt index 89b5963a3..371d36279 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/SecurityPreferencesFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/SecurityPreferencesFragment.kt @@ -26,7 +26,7 @@ import dev.ragnarok.fenrir.activity.ActivityUtils import dev.ragnarok.fenrir.activity.CreatePinActivity import dev.ragnarok.fenrir.crypt.KeyLocationPolicy import dev.ragnarok.fenrir.db.Stores -import dev.ragnarok.fenrir.fragment.createpin.CreatePinFragment +import dev.ragnarok.fenrir.fragment.pin.createpin.CreatePinFragment import dev.ragnarok.fenrir.fromIOToMain import dev.ragnarok.fenrir.listener.BackPressCallback import dev.ragnarok.fenrir.listener.CanBackPressedCallback diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AbsAttachmentsEditFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AbsAttachmentsEditFragment.kt index 545e6719d..2dc00a140 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AbsAttachmentsEditFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AbsAttachmentsEditFragment.kt @@ -28,8 +28,8 @@ import dev.ragnarok.fenrir.activity.PhotoAlbumsActivity import dev.ragnarok.fenrir.activity.PhotosActivity import dev.ragnarok.fenrir.db.model.AttachmentsTypes import dev.ragnarok.fenrir.fragment.base.BaseMvpFragment -import dev.ragnarok.fenrir.fragment.createpoll.CreatePollFragment -import dev.ragnarok.fenrir.fragment.vkphotos.IVKPhotosView +import dev.ragnarok.fenrir.fragment.photos.vkphotos.IVKPhotosView +import dev.ragnarok.fenrir.fragment.poll.createpoll.CreatePollFragment import dev.ragnarok.fenrir.getParcelableArrayListExtraCompat import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.listener.BackPressCallback @@ -342,12 +342,19 @@ abstract class AbsAttachmentsEditFragment

, V } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + parentFragmentManager.setFragmentResultListener( + CreatePollFragment.REQUEST_CREATE_POLL, + this + ) { _: String?, result: Bundle -> + val poll: Poll = result.getParcelableCompat("poll") ?: return@setFragmentResultListener + presenter?.firePollCreated(poll) + } + } + override fun openPollCreationWindow(accountId: Long, ownerId: Long) { getCreatePollPlace(accountId, ownerId) - .setFragmentListener(CreatePollFragment.REQUEST_CREATE_POLL) { _: String?, result: Bundle -> - val poll: Poll = result.getParcelableCompat("poll") ?: return@setFragmentListener - presenter?.firePollCreated(poll) - } .tryOpenWith(requireActivity()) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AttchmentsEditorAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AttchmentsEditorAdapter.kt index 85d6c808f..5221e7d1d 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AttchmentsEditorAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/absattachmentsedit/AttchmentsEditorAdapter.kt @@ -1,5 +1,6 @@ package dev.ragnarok.fenrir.fragment.attachments.absattachmentsedit +import android.annotation.SuppressLint import android.content.Context import android.graphics.Color import android.view.View @@ -306,11 +307,12 @@ class AttchmentsEditorAdapter( holder.photoImageView.setOnClickListener(null) } + @SuppressLint("SetTextI18n") private fun bindPoll(holder: ViewHolder, poll: Poll) { with() .load(R.drawable.background_gray) .into(holder.photoImageView) - holder.tvTitle.text = poll.question + holder.tvTitle.text = context.getString(R.string.poll) + " " + poll.question.orEmpty() holder.photoImageView.setOnClickListener(null) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/commentcreate/CommentCreateFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/commentcreate/CommentCreateFragment.kt index 1360c7e42..de4d79f85 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/commentcreate/CommentCreateFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/attachments/commentcreate/CommentCreateFragment.kt @@ -15,11 +15,9 @@ import dev.ragnarok.fenrir.fragment.attachments.absattachmentsedit.AbsAttachment import dev.ragnarok.fenrir.fragment.base.core.IPresenterFactory import dev.ragnarok.fenrir.listener.OnSectionResumeCallback - class CommentCreateFragment : AbsAttachmentsEditFragment(), ICreateCommentView, MenuProvider { - override fun getPresenterFactory(saveInstanceState: Bundle?): IPresenterFactory { return object : IPresenterFactory { override fun create(): CommentCreatePresenter { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/local/localaudioalbums/LocalAudioAlbumsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/local/localaudioalbums/LocalAudioAlbumsFragment.kt index 93d5835ae..a9f37b3b2 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/local/localaudioalbums/LocalAudioAlbumsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/local/localaudioalbums/LocalAudioAlbumsFragment.kt @@ -12,7 +12,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.fragment.base.BaseMvpBottomSheetDialogFragment import dev.ragnarok.fenrir.fragment.base.core.IPresenterFactory -import dev.ragnarok.fenrir.fragment.localimagealbums.LocalPhotoAlbumsAdapter +import dev.ragnarok.fenrir.fragment.photos.localimagealbums.LocalPhotoAlbumsAdapter import dev.ragnarok.fenrir.listener.PicassoPauseOnScrollListener import dev.ragnarok.fenrir.model.LocalImageAlbum import dev.ragnarok.fenrir.picasso.Content_Local diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/BaseMvpDialogFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/BaseMvpDialogFragment.kt index 0e9ae7ad1..067fc4d5c 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/BaseMvpDialogFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/BaseMvpDialogFragment.kt @@ -2,6 +2,7 @@ package dev.ragnarok.fenrir.fragment.base import android.graphics.Color import androidx.annotation.StringRes +import androidx.appcompat.app.AlertDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.BaseTransientBottomBar import dev.ragnarok.fenrir.Includes.provideApplicationContext @@ -11,8 +12,10 @@ import dev.ragnarok.fenrir.fragment.base.compat.AbsMvpDialogFragment import dev.ragnarok.fenrir.fragment.base.core.AbsPresenter import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView +import dev.ragnarok.fenrir.fragment.base.core.IProgressView import dev.ragnarok.fenrir.fragment.base.core.IToastView import dev.ragnarok.fenrir.service.ErrorLocalizer +import dev.ragnarok.fenrir.util.spots.SpotsDialog import dev.ragnarok.fenrir.util.toast.CustomSnackbars import dev.ragnarok.fenrir.util.toast.CustomToast import dev.ragnarok.fenrir.util.toast.CustomToast.Companion.createCustomToast @@ -20,8 +23,8 @@ import java.net.SocketTimeoutException import java.net.UnknownHostException abstract class BaseMvpDialogFragment

, V : IMvpView> : - AbsMvpDialogFragment(), IMvpView, IErrorView, IToastView { - + AbsMvpDialogFragment(), IMvpView, IProgressView, IErrorView, IToastView { + private var mLoadingProgressDialog: AlertDialog? = null override fun showError(errorText: String?) { if (isAdded) { customToast.showToastError(errorText) @@ -70,6 +73,24 @@ abstract class BaseMvpDialogFragment

, V : IMvpView> : } } + override fun displayProgressDialog( + @StringRes title: Int, + @StringRes message: Int, + cancelable: Boolean + ) { + dismissProgressDialog() + mLoadingProgressDialog = SpotsDialog.Builder().setContext(requireActivity()) + .setMessage(getString(title) + ": " + getString(message)).setCancelable(cancelable) + .build() + mLoadingProgressDialog?.show() + } + + override fun dismissProgressDialog() { + if (mLoadingProgressDialog?.isShowing == true) { + mLoadingProgressDialog?.cancel() + } + } + override val customToast: CustomToast get() = if (isAdded) { createCustomToast(requireActivity()) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/RecyclerBindableAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/RecyclerBindableAdapter.kt index f3ac3a794..6c35aec93 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/RecyclerBindableAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/base/RecyclerBindableAdapter.kt @@ -78,6 +78,10 @@ abstract class RecyclerBindableAdapter(private notifyItemRangeChanged(positionStart, itemCount) } + fun notifyItemBindableRangeRemoved(position: Int, count: Int) { + notifyItemRangeRemoved(position + headersCount, count) + } + fun notifyItemBindableRangeInserted(position: Int, count: Int) { notifyItemRangeInserted(position + headersCount, count) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/comments/CommentsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/comments/CommentsFragment.kt index 786472b5f..0e7e3182f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/comments/CommentsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/comments/CommentsFragment.kt @@ -95,6 +95,30 @@ class CommentsFragment : PlaceSupportMvpFragment + val body = result.getString(Extra.BODY) + lazyPresenter { + fireEditBodyResult(body) + } + } + + parentFragmentManager.setFragmentResultListener( + CommentEditFragment.REQUEST_COMMENT_EDIT, + this + ) { _: String?, result: Bundle -> + val comment1: Comment? = result.getParcelableCompat( + Extra.COMMENT + ) + if (comment1 != null) { + lazyPresenter { + fireCommentEditResult(comment1) + } + } + } } override fun onCreateView( @@ -266,12 +290,6 @@ class CommentsFragment : PlaceSupportMvpFragment - val body = result.getString(Extra.BODY) - lazyPresenter { - fireEditBodyResult(body) - } - } .tryOpenWith(requireActivity()) } @@ -296,16 +314,6 @@ class CommentsFragment : PlaceSupportMvpFragment - val comment1: Comment? = result.getParcelableCompat( - Extra.COMMENT - ) - if (comment1 != null) { - lazyPresenter { - fireCommentEditResult(comment1) - } - } - } .tryOpenWith(requireActivity()) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/CommunityControlFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/CommunityControlFragment.kt similarity index 91% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/CommunityControlFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/CommunityControlFragment.kt index 37ef55ca7..d3f9a940f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/CommunityControlFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/CommunityControlFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol +package dev.ragnarok.fenrir.fragment.communities.communitycontrol import android.os.Bundle import android.view.LayoutInflater @@ -15,10 +15,10 @@ import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.activity.ActivityFeatures import dev.ragnarok.fenrir.activity.ActivityUtils.setToolbarSubtitle import dev.ragnarok.fenrir.activity.ActivityUtils.setToolbarTitle -import dev.ragnarok.fenrir.fragment.communitycontrol.communityblacklist.CommunityBlacklistFragment.Companion.newInstance -import dev.ragnarok.fenrir.fragment.communitycontrol.communitylinks.CommunityLinksFragment -import dev.ragnarok.fenrir.fragment.communitycontrol.communitymanagers.CommunityManagersFragment.Companion.newInstance -import dev.ragnarok.fenrir.fragment.communitycontrol.communityoptions.CommunityOptionsFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityblacklist.CommunityBlacklistFragment.Companion.newInstance +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitylinks.CommunityLinksFragment +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanagers.CommunityManagersFragment.Companion.newInstance +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityoptions.CommunityOptionsFragment import dev.ragnarok.fenrir.getParcelableCompat import dev.ragnarok.fenrir.listener.OnSectionResumeCallback import dev.ragnarok.fenrir.model.Community diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditFragment.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditFragment.kt index 7ca133011..afa8cfc8d 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityban +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban import android.content.DialogInterface import android.os.Bundle diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditPresenter.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditPresenter.kt index e54364bf8..60309c1f4 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBanEditPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBanEditPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityban +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban import android.os.Bundle import dev.ragnarok.fenrir.R diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBannedAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBannedAdapter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBannedAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBannedAdapter.kt index 23bf02a34..94b369922 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/CommunityBannedAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/CommunityBannedAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityban +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban import android.text.method.LinkMovementMethod import android.view.LayoutInflater diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/ICommunityBanEditView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/ICommunityBanEditView.kt similarity index 91% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/ICommunityBanEditView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/ICommunityBanEditView.kt index 10ea4e657..0db944103 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityban/ICommunityBanEditView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityban/ICommunityBanEditView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityban +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt similarity index 97% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt index 2dd80e561..df13d85fd 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityblacklist +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityblacklist import android.app.Activity import android.content.DialogInterface @@ -17,7 +17,7 @@ import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.activity.selectprofiles.SelectProfilesActivity.Companion.createIntent import dev.ragnarok.fenrir.fragment.base.BaseMvpFragment import dev.ragnarok.fenrir.fragment.base.core.IPresenterFactory -import dev.ragnarok.fenrir.fragment.communitycontrol.communityban.CommunityBannedAdapter +import dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityban.CommunityBannedAdapter import dev.ragnarok.fenrir.fragment.search.SearchContentType import dev.ragnarok.fenrir.fragment.search.criteria.PeopleSearchCriteria import dev.ragnarok.fenrir.getParcelableArrayListExtraCompat diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt index 2af446d00..664c8471e 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/CommunityBlacklistPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityblacklist +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityblacklist import android.os.Bundle import dev.ragnarok.fenrir.Includes.networkInterfaces diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/ICommunityBlacklistView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/ICommunityBlacklistView.kt similarity index 89% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/ICommunityBlacklistView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/ICommunityBlacklistView.kt index 1b95f030e..7ab40d5f3 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityblacklist/ICommunityBlacklistView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityblacklist/ICommunityBlacklistView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityblacklist +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityblacklist import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt similarity index 97% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt index 84ecda6b9..ad62c89ec 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfocontacts +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfocontacts import android.view.LayoutInflater import android.view.View diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt similarity index 97% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt index 4eaf86972..4b570ce63 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfocontacts +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfocontacts import android.os.Bundle import android.view.LayoutInflater diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt index 675b7030e..3895fd81e 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/CommunityInfoContactsPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfocontacts +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfocontacts import android.os.Bundle import dev.ragnarok.fenrir.Includes.networkInterfaces diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt similarity index 87% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt index 55ce0d45f..cf7e87c0a 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfocontacts/ICommunityInfoContactsView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfocontacts +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfocontacts import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt similarity index 96% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt index 164ff3f48..adc657dc1 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfolinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfolinks import android.view.LayoutInflater import android.view.View diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt similarity index 97% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt index b7eb85344..09c45eb8d 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfolinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfolinks import android.content.Intent import android.net.Uri diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt similarity index 96% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt index 73a5e1b7c..ecd4df88e 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/CommunityInfoLinksPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfolinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfolinks import android.os.Bundle import dev.ragnarok.fenrir.Includes.networkInterfaces diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt similarity index 82% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt index cc3213a1f..a5dd031a2 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityinfolinks/ICommunityInfoLinksView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityinfolinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityinfolinks import dev.ragnarok.fenrir.api.model.VKApiCommunity import dev.ragnarok.fenrir.fragment.base.core.IErrorView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksAdapter.kt similarity index 96% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksAdapter.kt index 0d8fd6a29..6cd921cb0 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitylinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitylinks import android.view.LayoutInflater import android.view.View diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksFragment.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksFragment.kt index 1705b676f..4807a5ec5 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitylinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitylinks import android.content.DialogInterface import android.content.Intent diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksPresenter.kt similarity index 96% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksPresenter.kt index f204bb250..a069e02d7 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/CommunityLinksPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/CommunityLinksPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitylinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitylinks import android.os.Bundle import dev.ragnarok.fenrir.Includes.networkInterfaces diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/ICommunityLinksView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/ICommunityLinksView.kt similarity index 82% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/ICommunityLinksView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/ICommunityLinksView.kt index 87c0c0a5d..0bdbc9f1b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitylinks/ICommunityLinksView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitylinks/ICommunityLinksView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitylinks +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitylinks import dev.ragnarok.fenrir.api.model.VKApiCommunity import dev.ragnarok.fenrir.fragment.base.core.IErrorView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt index 0d802d281..f8f0428d6 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanageredit +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanageredit import android.os.Bundle import android.view.LayoutInflater diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt index 3409c7078..6a150b6ff 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/CommunityManagerEditPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanageredit +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanageredit import android.os.Bundle import dev.ragnarok.fenrir.R diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt similarity index 90% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt index 486e5a5a8..188245361 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanageredit/ICommunityManagerEditView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanageredit +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanageredit import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersAdapter.kt similarity index 97% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersAdapter.kt index 21918d448..099390535 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanagers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanagers import android.view.LayoutInflater import android.view.View diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersFragment.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersFragment.kt index 8ca15dc3e..08efd2c00 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanagers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanagers import android.app.Activity import android.content.DialogInterface diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersPresenter.kt index 81535b621..8560c78b6 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/CommunityManagersPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/CommunityManagersPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanagers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanagers import android.os.Bundle import dev.ragnarok.fenrir.Includes.networkInterfaces diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/ICommunityManagersView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/ICommunityManagersView.kt similarity index 90% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/ICommunityManagersView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/ICommunityManagersView.kt index 2903e447a..a91e3ac94 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymanagers/ICommunityManagersView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymanagers/ICommunityManagersView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymanagers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymanagers import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersFragment.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersFragment.kt index 52e7f8cbe..69b7c1985 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymembers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymembers import android.os.Bundle import android.view.LayoutInflater diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersPresenter.kt index 04dde1154..4c2f807f2 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/CommunityMembersPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/CommunityMembersPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymembers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymembers import android.os.Bundle import dev.ragnarok.fenrir.domain.IRelationshipInteractor diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/ICommunityMembersView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/ICommunityMembersView.kt similarity index 88% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/ICommunityMembersView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/ICommunityMembersView.kt index 3c4476feb..d4d798ae9 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communitymembers/ICommunityMembersView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communitymembers/ICommunityMembersView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communitymembers +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communitymembers import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsFragment.kt similarity index 99% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsFragment.kt index 0bb3ad8cb..3a8aacfcc 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityoptions +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityoptions import android.content.DialogInterface import android.os.Bundle diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsPresenter.kt index a4a7cc9f8..e5fb5f85f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/CommunityOptionsPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/CommunityOptionsPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityoptions +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityoptions import android.os.Bundle import dev.ragnarok.fenrir.R diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/ICommunityOptionsView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/ICommunityOptionsView.kt similarity index 93% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/ICommunityOptionsView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/ICommunityOptionsView.kt index 078f4c5a6..f39c7ff3b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communitycontrol/communityoptions/ICommunityOptionsView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/communitycontrol/communityoptions/ICommunityOptionsView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.communitycontrol.communityoptions +package dev.ragnarok.fenrir.fragment.communities.communitycontrol.communityoptions import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsAdapter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsAdapter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsAdapter.kt index 4e1a583c0..af312a514 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsAdapter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.groupchats +package dev.ragnarok.fenrir.fragment.communities.groupchats import android.content.ClipData import android.content.ClipboardManager diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsFragment.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsFragment.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsFragment.kt index 745333257..ae6c6d270 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.groupchats +package dev.ragnarok.fenrir.fragment.communities.groupchats import android.content.DialogInterface import android.os.Bundle diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsPresenter.kt similarity index 98% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsPresenter.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsPresenter.kt index 539938223..b2c24689f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/GroupChatsPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/GroupChatsPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.groupchats +package dev.ragnarok.fenrir.fragment.communities.groupchats import android.os.Bundle import dev.ragnarok.fenrir.domain.IOwnersRepository diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/IGroupChatsView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/IGroupChatsView.kt similarity index 89% rename from app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/IGroupChatsView.kt rename to app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/IGroupChatsView.kt index 16b12191b..819fa5b48 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/groupchats/IGroupChatsView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/communities/groupchats/IGroupChatsView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.fenrir.fragment.groupchats +package dev.ragnarok.fenrir.fragment.communities.groupchats import dev.ragnarok.fenrir.fragment.base.core.IErrorView import dev.ragnarok.fenrir.fragment.base.core.IMvpView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationaudios/IChatAttachmentAudiosView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationaudios/IChatAttachmentAudiosView.kt deleted file mode 100644 index ef638b2c0..000000000 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/conversation/conversationaudios/IChatAttachmentAudiosView.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.ragnarok.fenrir.fragment.conversation.conversationaudios - -import dev.ragnarok.fenrir.fragment.conversation.abschatattachments.IBaseChatAttachmentsView -import dev.ragnarok.fenrir.model.Audio - -interface IChatAttachmentAudiosView : IBaseChatAttachmentsView

+ * This annotation also could be used as a meta-annotation, to define derived annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent Java methods: + * + *

+ *   @Language(value = "JAVA", prefix = "class X{", suffix = "}")
+ *   @interface JavaMethod {}
+ * 
+ *

+ * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + */ + +@InternalSerializationApi +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.ANNOTATION_CLASS +) +annotation class FormatLanguage( + val value: String, + // default parameters are not used due to https://youtrack.jetbrains.com/issue/KT-25946/ + val prefix: String, + val suffix: String, +) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/JsonIterator.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/JsonIterator.kt index 52cecfc4f..e59df1f5b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/JsonIterator.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/JsonIterator.kt @@ -73,6 +73,7 @@ private class JsonIteratorArrayWrapped( private val deserializer: DeserializationStrategy ) : Iterator { private var first = true + private var finished = false override fun next(): T { if (first) { @@ -88,7 +89,9 @@ private class JsonIteratorArrayWrapped( * Note: if array separator (comma) is missing, hasNext() returns true, but next() throws an exception. */ override fun hasNext(): Boolean { + if (finished) return false if (lexer.peekNextToken() == TC_END_LIST) { + finished = true lexer.consumeNextToken(TC_END_LIST) if (lexer.isNotEof()) { if (lexer.peekNextToken() == TC_BEGIN_LIST) lexer.fail( @@ -100,7 +103,7 @@ private class JsonIteratorArrayWrapped( } return false } - if (!lexer.isNotEof()) lexer.fail(TC_END_LIST) + if (!lexer.isNotEof() && !finished) lexer.fail(TC_END_LIST) return true } } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/StreamingJsonDecoder.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/StreamingJsonDecoder.kt index 38b3967d2..064a73232 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/StreamingJsonDecoder.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/StreamingJsonDecoder.kt @@ -98,6 +98,9 @@ internal open class StreamingJsonDecoder( return actualSerializer.deserialize(this) as T } catch (e: MissingFieldException) { + // Add "at path" if and only if we've just caught an exception and it hasn't been augmented yet + if (e.message?.contains("at path") == true) throw e + // NB: we could've use some additional flag marker or augment the stacktrace, but it seemed to be as too much of a burden throw MissingFieldException( e.missingFields, e.message + " at path: " + lexer.path.getPath(), diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonDecoder.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonDecoder.kt index ed7e3a2df..6d2a1fc9b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonDecoder.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonDecoder.kt @@ -202,9 +202,14 @@ private sealed class AbstractJsonTreeDecoder( ), json ) else super.decodeTaggedInline(tag, inlineDescriptor) + + override fun decodeInline(descriptor: SerialDescriptor): Decoder { + return if (currentTagOrNull != null) super.decodeInline(descriptor) + else JsonPrimitiveDecoder(json, value).decodeInline(descriptor) + } } -private class JsonPrimitiveDecoder(json: Json, override val value: JsonPrimitive) : +private class JsonPrimitiveDecoder(json: Json, override val value: JsonElement) : AbstractJsonTreeDecoder(json, value) { init { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonEncoder.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonEncoder.kt index f2c2193f1..73a24ad04 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonEncoder.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/TreeJsonEncoder.kt @@ -29,7 +29,7 @@ fun Json.writeJson(value: T, serializer: SerializationStrategy): JsonElem @ExperimentalSerializationApi private sealed class AbstractJsonTreeEncoder( final override val json: Json, - private val nodeConsumer: (JsonElement) -> Unit + protected val nodeConsumer: (JsonElement) -> Unit ) : NamedValueEncoder(), JsonEncoder { final override val serializersModule: SerializersModule @@ -86,7 +86,6 @@ private sealed class AbstractJsonTreeEncoder( encodePolymorphically(serializer, value) { polymorphicDiscriminator = it } } else JsonPrimitiveEncoder(json, nodeConsumer).apply { encodeSerializableValue(serializer, value) - endEncode(serializer.descriptor) } } @@ -128,6 +127,11 @@ private sealed class AbstractJsonTreeEncoder( else -> super.encodeTaggedInline(tag, inlineDescriptor) } + override fun encodeInline(descriptor: SerialDescriptor): Encoder { + return if (currentTagOrNull != null) super.encodeInline(descriptor) + else JsonPrimitiveEncoder(json, nodeConsumer).encodeInline(descriptor) + } + @SuppressAnimalSniffer // Long(Integer).toUnsignedString(long) private fun inlineUnsignedNumberEncoder(tag: String) = object : AbstractEncoder() { override val serializersModule: SerializersModule = json.serializersModule @@ -197,6 +201,7 @@ private class JsonPrimitiveEncoder( require(key === PRIMITIVE_TAG) { "This output can only consume primitives with '$PRIMITIVE_TAG' tag" } require(content == null) { "Primitive element was already recorded. Does call to .encodeXxx happen more than once?" } content = element + nodeConsumer(element) } override fun getCurrent(): JsonElement = diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/lexer/JsonLexer.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/lexer/JsonLexer.kt index 438141122..0b05bedcf 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/lexer/JsonLexer.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/json/internal/lexer/JsonLexer.kt @@ -33,6 +33,9 @@ internal class ArrayAsSequence(private val buffer: CharArray) : CharSequence { fun trim(newSize: Int) { length = minOf(buffer.size, newSize) } + + // source.toString() is used in JsonDecodingException + override fun toString(): String = substring(0, length) } internal class ReaderJsonLexer( diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/MsgPackConfiguration.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/MsgPackConfiguration.kt index e48ef2531..1ab49cd51 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/MsgPackConfiguration.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/MsgPackConfiguration.kt @@ -35,7 +35,12 @@ data class MsgPackConfiguration( * Useful when only parts of data are of interest * false by default */ - val ignoreUnknownKeys: Boolean = true + val ignoreUnknownKeys: Boolean = true, + /** + * Encode enum values as Ints corresponding to their ordinal values + * false by default + */ + val ordinalEnums: Boolean = false ) { companion object { val default: MsgPackConfiguration = MsgPackConfiguration() diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt index 6e0539ada..43dbc134e 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt @@ -32,7 +32,7 @@ abstract class BaseMsgPackExtensionSerializer : KSerializer { extension.extTypeId ) } - encoder.encodeSerializableValue(serializer, serialize(value)) + encoder.encodeSerializableValue(serializer, extension) } abstract fun deserialize(extension: MsgPackExtension): T diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackDecoder.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackDecoder.kt index 389a4281e..1be8c5089 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackDecoder.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackDecoder.kt @@ -117,6 +117,9 @@ internal class BasicMsgPackDecoder( } override fun decodeEnum(enumDescriptor: SerialDescriptor): Int { + if (configuration.ordinalEnums) { + return msgUnpacker.unpackInt(configuration.strictTypes, configuration.preventOverflows) + } return enumDescriptor.getElementIndex(decodeString()) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackEncoder.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackEncoder.kt index ecea67454..7e80b02be 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackEncoder.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/serializeble/msgpack/internal/MsgPackEncoder.kt @@ -64,12 +64,16 @@ internal class BasicMsgPackEncoder( } override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { - result.addAll( - packer.packString( - enumDescriptor.getElementName(index), - configuration.rawCompatibility + if (configuration.ordinalEnums) { + result.addAll(packer.packInt(index, configuration.strictTypeWriting)) + } else { + result.addAll( + packer.packString( + enumDescriptor.getElementName(index), + configuration.rawCompatibility + ) ) - ) + } } fun encodeByteArray(value: ByteArray) { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/PollGradientDrawable.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/PollGradientDrawable.kt new file mode 100644 index 000000000..5c56e80ea --- /dev/null +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/PollGradientDrawable.kt @@ -0,0 +1,122 @@ +package dev.ragnarok.fenrir.view + +import android.graphics.Canvas +import android.graphics.ColorFilter +import android.graphics.LinearGradient +import android.graphics.Paint +import android.graphics.Path +import android.graphics.PixelFormat +import android.graphics.Shader +import android.graphics.drawable.Drawable +import dev.ragnarok.fenrir.Constants +import dev.ragnarok.fenrir.model.Poll +import kotlin.math.cos +import kotlin.math.pow +import kotlin.math.sin +import kotlin.math.sqrt + + +class PollGradientDrawable(val pollBackground: Poll.PollBackground) : + Drawable() { + private val DEFAULT_RADIUS = 26f + private val PATH = Path() + private val paint = + Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG) + + override fun draw(canvas: Canvas) { + try { + val widthTmp = bounds.width() + val heightTmp = bounds.height() + if (widthTmp <= 0 || heightTmp <= 0) { + return + } + val r = sqrt( + heightTmp.toDouble().pow(2.0) + + widthTmp.toDouble().pow(2.0) + ) / 2 + val centerX: Float = widthTmp.toFloat() / 2 + val centerY: Float = heightTmp.toFloat() / 2 + + val sTmp = (sin(Math.toRadians(pollBackground.angle.toDouble())) * r).toFloat() + val cTmp = (cos(Math.toRadians(pollBackground.angle.toDouble())) * r).toFloat() + + val startX = 0f.coerceAtLeast(widthTmp.toFloat().coerceAtMost(centerX - cTmp)) + val startY = heightTmp.toFloat().coerceAtMost(0f.coerceAtLeast(centerY - sTmp)) + + val endX = 0f.coerceAtLeast(widthTmp.toFloat().coerceAtMost(centerX + cTmp)) + val endY = heightTmp.toFloat().coerceAtMost(0f.coerceAtLeast(centerY + sTmp)) + + paint.shader = LinearGradient( + startX, + startY, + endX, + endY, + pollBackground.getColors(), + pollBackground.getPositions(), + Shader.TileMode.CLAMP + ) + PATH.reset() + PATH.moveTo(0f, DEFAULT_RADIUS) + PATH.arcTo(0f, 0f, 2 * DEFAULT_RADIUS, 2 * DEFAULT_RADIUS, 180f, 90f, false) + PATH.lineTo(widthTmp - DEFAULT_RADIUS, 0f) + PATH.arcTo( + widthTmp - 2 * DEFAULT_RADIUS, + 0f, + widthTmp.toFloat(), + 2 * DEFAULT_RADIUS, + 270f, + 90f, + false + ) + PATH.lineTo(widthTmp.toFloat(), heightTmp - DEFAULT_RADIUS) + PATH.arcTo( + widthTmp - 2 * DEFAULT_RADIUS, + heightTmp - 2 * DEFAULT_RADIUS, + widthTmp.toFloat(), + heightTmp.toFloat(), + 0f, + 90f, + false + ) + PATH.lineTo(DEFAULT_RADIUS, heightTmp.toFloat()) + PATH.arcTo( + 0f, + heightTmp - 2 * DEFAULT_RADIUS, + 2 * DEFAULT_RADIUS, + heightTmp.toFloat(), + 90f, + 90f, + false + ) + PATH.lineTo(0f, DEFAULT_RADIUS) + PATH.close() + canvas.drawPath(PATH, paint) + } catch (e: Exception) { + if (Constants.IS_DEBUG) { + e.printStackTrace() + } + } + } + + override fun setAlpha(alpha: Int) { + paint.alpha = alpha + invalidateSelf() + } + + override fun setColorFilter(colorFilter: ColorFilter?) { + throw UnsupportedOperationException("setColorFilter unsupported!") + } + + @Deprecated( + "Deprecated in Java", + ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat") + ) + override fun getOpacity(): Int { + return PixelFormat.TRANSLUCENT + } + + init { + paint.alpha = 220 + paint.style = Paint.Style.FILL + } +} diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/ProfileCoverDrawable.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/ProfileCoverDrawable.kt index 6e74966bc..256272581 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/ProfileCoverDrawable.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/ProfileCoverDrawable.kt @@ -28,6 +28,9 @@ class ProfileCoverDrawable(private val bitmap: Bitmap, private val targetAlpha: } private fun printBitmap(canvas: Canvas) { + if (bounds.width() <= 0 || bounds.height() <= 0) { + return + } val pScale = determineImageScale(bounds.width(), bounds.height(), bitmap.width, bitmap.height) val px = bounds.width() * pScale diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RecyclerViewSavedScroll.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RecyclerViewSavedScroll.kt new file mode 100644 index 000000000..5943bfd19 --- /dev/null +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RecyclerViewSavedScroll.kt @@ -0,0 +1,48 @@ +package dev.ragnarok.fenrir.view + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Parcelable +import android.util.AttributeSet +import androidx.recyclerview.widget.RecyclerView + +@SuppressLint("CustomViewStyleable", "PrivateResource") +class RecyclerViewSavedScroll @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null +) : RecyclerView(context, attrs) { + private var uid: Int = -1 + + fun updateUid(uid: Int?) { + this.uid = uid ?: -1 + if (uid == -1) { + return + } + parcelables[uid]?.let { + try { + layoutManager?.onRestoreInstanceState(it) + } catch (_: Exception) { + } + } + } + + fun saveState() { + if (uid == -1) { + return + } + parcelables[uid] = layoutManager?.onSaveInstanceState() + } + + override fun onDetachedFromWindow() { + if (uid == -1) { + super.onDetachedFromWindow() + return + } + parcelables[uid] = layoutManager?.onSaveInstanceState() + super.onDetachedFromWindow() + } + + companion object { + private var parcelables = HashMap() + } +} diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RoundCornerLinearView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RoundCornerLinearView.kt index c713f6af0..1a2c29c1a 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RoundCornerLinearView.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/RoundCornerLinearView.kt @@ -64,39 +64,42 @@ class RoundCornerLinearView : LinearLayout { override fun onDraw(canvas: Canvas) { super.onDraw(canvas) + val widthTmp = width + val heightTmp = height + if (widthTmp <= 0 || heightTmp <= 0) { + return + } FILL_PAINT.color = color FILL_PAINT.shader = null - val width = width - val height = height PATH.reset() PATH.moveTo(0f, radius_top_left) PATH.arcTo(0f, 0f, 2 * radius_top_left, 2 * radius_top_left, 180f, 90f, false) - PATH.lineTo(width - radius_top_right, 0f) + PATH.lineTo(widthTmp - radius_top_right, 0f) PATH.arcTo( - width - 2 * radius_top_right, + widthTmp - 2 * radius_top_right, 0f, - width.toFloat(), + widthTmp.toFloat(), 2 * radius_top_right, 270f, 90f, false ) - PATH.lineTo(width.toFloat(), height - radius_bottom_right) + PATH.lineTo(widthTmp.toFloat(), heightTmp - radius_bottom_right) PATH.arcTo( - width - 2 * radius_bottom_right, - height - 2 * radius_bottom_right, - width.toFloat(), - height.toFloat(), + widthTmp - 2 * radius_bottom_right, + heightTmp - 2 * radius_bottom_right, + widthTmp.toFloat(), + heightTmp.toFloat(), 0f, 90f, false ) - PATH.lineTo(radius_bottom_left, height.toFloat()) + PATH.lineTo(radius_bottom_left, heightTmp.toFloat()) PATH.arcTo( 0f, - height - 2 * radius_bottom_left, + heightTmp - 2 * radius_bottom_left, 2 * radius_bottom_left, - height.toFloat(), + heightTmp.toFloat(), 90f, 90f, false diff --git a/app_fenrir/src/main/res/drawable/photo_sizes.xml b/app_fenrir/src/main/res/drawable/photo_sizes.xml index 77806dd54..5a057542d 100644 --- a/app_fenrir/src/main/res/drawable/photo_sizes.xml +++ b/app_fenrir/src/main/res/drawable/photo_sizes.xml @@ -1,7 +1,7 @@ - + android:layout_marginStart="8dp" + app:icon="@drawable/send" /> diff --git a/app_fenrir/src/main/res/layout/bottom_sheet_attachments_edit.xml b/app_fenrir/src/main/res/layout/bottom_sheet_attachments_edit.xml index 935ff5d19..4318d7586 100644 --- a/app_fenrir/src/main/res/layout/bottom_sheet_attachments_edit.xml +++ b/app_fenrir/src/main/res/layout/bottom_sheet_attachments_edit.xml @@ -49,6 +49,17 @@ android:orientation="horizontal" android:padding="8dp"> + + + android:layout_marginStart="8dp" + app:icon="@drawable/check" /> diff --git a/app_fenrir/src/main/res/layout/fragment_create_poll.xml b/app_fenrir/src/main/res/layout/fragment_create_poll.xml index 1c8be57bc..2bf612b08 100644 --- a/app_fenrir/src/main/res/layout/fragment_create_poll.xml +++ b/app_fenrir/src/main/res/layout/fragment_create_poll.xml @@ -2,6 +2,7 @@ @@ -13,35 +14,22 @@ - - - + android:layout_marginTop="4dp"> - + + - + android:layout_marginTop="4dp"> - + + + + android:layout_marginTop="8dp"> - + + + + android:layout_marginTop="8dp"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> - + + + + android:visibility="gone"> + + + - + + - + - \ No newline at end of file + diff --git a/app_fenrir/src/main/res/layout/fragment_create_poll_dialog.xml b/app_fenrir/src/main/res/layout/fragment_create_poll_dialog.xml new file mode 100644 index 000000000..67c2dc109 --- /dev/null +++ b/app_fenrir/src/main/res/layout/fragment_create_poll_dialog.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_fenrir/src/main/res/layout/fragment_poll.xml b/app_fenrir/src/main/res/layout/fragment_poll.xml index 23d793e50..e560f825e 100644 --- a/app_fenrir/src/main/res/layout/fragment_poll.xml +++ b/app_fenrir/src/main/res/layout/fragment_poll.xml @@ -45,6 +45,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" android:animateLayoutChanges="true" android:foreground="?attr/selectableItemBackground" app:button_text="@string/add_vote" /> diff --git a/app_fenrir/src/main/res/layout/fragment_wall_attachments.xml b/app_fenrir/src/main/res/layout/fragment_wall_attachments.xml index a4c292402..754cadd93 100644 --- a/app_fenrir/src/main/res/layout/fragment_wall_attachments.xml +++ b/app_fenrir/src/main/res/layout/fragment_wall_attachments.xml @@ -4,7 +4,30 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + + + + + + + - + + + + + + + - + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> @@ -50,5 +63,6 @@ android:layout_margin="@dimen/fab_margin" android:contentDescription="@null" android:src="@drawable/comment" + android:visibility="gone" app:maxImageSize="30dp" /> \ No newline at end of file diff --git a/app_fenrir/src/main/res/layout/item_poll_background.xml b/app_fenrir/src/main/res/layout/item_poll_background.xml new file mode 100644 index 000000000..3763232ff --- /dev/null +++ b/app_fenrir/src/main/res/layout/item_poll_background.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + diff --git a/app_fenrir/src/main/res/layout/item_wall_attachments_recycler.xml b/app_fenrir/src/main/res/layout/item_wall_attachments_recycler.xml new file mode 100644 index 000000000..38c84f7d8 --- /dev/null +++ b/app_fenrir/src/main/res/layout/item_wall_attachments_recycler.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/app_fenrir/src/main/res/menu/menu_chat.xml b/app_fenrir/src/main/res/menu/menu_chat.xml index dc88e622c..538af3856 100644 --- a/app_fenrir/src/main/res/menu/menu_chat.xml +++ b/app_fenrir/src/main/res/menu/menu_chat.xml @@ -63,8 +63,8 @@ android:title="@string/short_link" /> + android:id="@+id/change_chrono_history" + android:title="@string/change_chrono_history" /> Агульныя Аб дадатку Ачысціць кэш і базу дадзеных + Ачысціць кэш і базу дадзеных? Ачысціць кэш Да дыялогу @@ -732,7 +733,7 @@ Матэрыялы гутаркі Матэрыялы сцяны Чат Json (%1$d паведамленняў) - Паказаць пачатак + Паказаць пачатак Профіль невядома %1$d фота @@ -1030,7 +1031,6 @@ Фота ВК Лакальныя фота Галерэя - Адпр. Укладанняў пакуль няма (ліміт 10) Дадаць фота/відэа Выключэнні @@ -1403,6 +1403,7 @@ Быць анлайн Укладанні на сцяне %1$d пастоў праверана + %1$d паведамленняў праверана %1$d каментароў праверана Скругленне краёў малюнкаў Памер шрыфта @@ -1717,4 +1718,6 @@ Кліпы Гісторыі Акаўнт не зарэгістраваны! + Забараніць адмену голасу + Пусты фон \ No newline at end of file diff --git a/app_fenrir/src/main/res/values-ru/strings.xml b/app_fenrir/src/main/res/values-ru/strings.xml index c68e13bee..fadeb79b1 100644 --- a/app_fenrir/src/main/res/values-ru/strings.xml +++ b/app_fenrir/src/main/res/values-ru/strings.xml @@ -137,6 +137,7 @@ Общие О приложении Очистить кэш и базу данных + Очистить кэш и базу данных? Очистить кэш К диалогу @@ -730,10 +731,10 @@ Нет изображений Нет видео %1$s приглашает Вас вступить в сообщество - Материалы беседы + Материалы диалога Материалы стены Чат Json (%1$d сообщений) - Показать начало + Показать начало Профиль неизвестно %1$d фото @@ -1032,7 +1033,6 @@ Фото ВК Локальные фото Галерея - Отпр. Вложений пока нет (лимит 10) Добавить фото/видео Исключения @@ -1405,6 +1405,7 @@ Быть онлайн Вложения на стене %1$d постов проверено + %1$d сообщений проверено %1$d комментариев проверено Скругление краёв изображений Размер шрифта @@ -1719,4 +1720,6 @@ Клипы Истории Аккаунт не зарегистрирован! + Запретить отмену голоса + Пустой фон \ No newline at end of file diff --git a/app_fenrir/src/main/res/values/strings.xml b/app_fenrir/src/main/res/values/strings.xml index 39a38604a..3b1aff62b 100644 --- a/app_fenrir/src/main/res/values/strings.xml +++ b/app_fenrir/src/main/res/values/strings.xml @@ -291,6 +291,7 @@ Commons About application Clear cache and sql + Do clear cache and sql? Clear cache To dialog @@ -932,7 +933,7 @@ Chat materials Wall materials Chat JSON (%1$d messages) - Show start + Show start Profile unknown %1$d photo @@ -1252,7 +1253,6 @@ Photo VK Local photos Gallery - Send No attachments yet (limit 10) Add photo/video Exceptions @@ -1641,6 +1641,7 @@ Stay online Wall attachments %1$d posts checked + %1$d messages checked %1$d comments checked Round image edges Font size @@ -1956,4 +1957,6 @@ Clips Stories Account not registered! + Disable unvote + Empty Background diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/CreatePinActivity.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/CreatePinActivity.kt index ed2f52282..906f58ebd 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/CreatePinActivity.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/CreatePinActivity.kt @@ -2,7 +2,7 @@ package dev.ragnarok.filegallery.activity import android.os.Bundle import dev.ragnarok.filegallery.R -import dev.ragnarok.filegallery.fragment.createpin.CreatePinFragment +import dev.ragnarok.filegallery.fragment.pin.createpin.CreatePinFragment class CreatePinActivity : NoMainActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/EnterPinActivity.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/EnterPinActivity.kt index 8fddb8166..7ca6a63e5 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/EnterPinActivity.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/EnterPinActivity.kt @@ -3,7 +3,7 @@ package dev.ragnarok.filegallery.activity import android.content.Context import android.os.Bundle import dev.ragnarok.filegallery.R -import dev.ragnarok.filegallery.fragment.enterpin.EnterPinFragment +import dev.ragnarok.filegallery.fragment.pin.enterpin.EnterPinFragment import dev.ragnarok.filegallery.util.Utils open class EnterPinActivity : NoMainActivity() { diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/SecurityPreferencesFragment.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/SecurityPreferencesFragment.kt index c8a0b6f32..1cd086328 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/SecurityPreferencesFragment.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/SecurityPreferencesFragment.kt @@ -21,7 +21,7 @@ import dev.ragnarok.filegallery.R import dev.ragnarok.filegallery.activity.ActivityFeatures import dev.ragnarok.filegallery.activity.ActivityUtils import dev.ragnarok.filegallery.activity.CreatePinActivity -import dev.ragnarok.filegallery.fragment.createpin.CreatePinFragment +import dev.ragnarok.filegallery.fragment.pin.createpin.CreatePinFragment import dev.ragnarok.filegallery.fromIOToMain import dev.ragnarok.filegallery.listener.BackPressCallback import dev.ragnarok.filegallery.listener.CanBackPressedCallback diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinFragment.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinFragment.kt similarity index 98% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinFragment.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinFragment.kt index 57d7f0ba1..e1bc2c99d 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinFragment.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.createpin +package dev.ragnarok.filegallery.fragment.pin.createpin import android.app.Activity import android.content.Intent diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinPresenter.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinPresenter.kt similarity index 99% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinPresenter.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinPresenter.kt index f5e20c1dd..099ec6619 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/CreatePinPresenter.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/CreatePinPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.createpin +package dev.ragnarok.filegallery.fragment.pin.createpin import android.os.Bundle import android.os.Handler diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/ICreatePinView.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/ICreatePinView.kt similarity index 87% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/ICreatePinView.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/ICreatePinView.kt index 61c0717dc..0f4c7eff9 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/createpin/ICreatePinView.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/createpin/ICreatePinView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.createpin +package dev.ragnarok.filegallery.fragment.pin.createpin import androidx.annotation.StringRes import dev.ragnarok.filegallery.fragment.base.core.IErrorView diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinFragment.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinFragment.kt similarity index 98% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinFragment.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinFragment.kt index 67710dc73..9bb989de9 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinFragment.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinFragment.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.enterpin +package dev.ragnarok.filegallery.fragment.pin.enterpin import android.app.Activity import android.content.Intent diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinPresenter.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinPresenter.kt similarity index 98% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinPresenter.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinPresenter.kt index d5e26ef96..262c039bc 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/EnterPinPresenter.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/EnterPinPresenter.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.enterpin +package dev.ragnarok.filegallery.fragment.pin.enterpin import android.os.Bundle import android.os.Handler diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/IEnterPinView.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/IEnterPinView.kt similarity index 87% rename from app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/IEnterPinView.kt rename to app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/IEnterPinView.kt index 506655bf3..462e69630 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/enterpin/IEnterPinView.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/fragment/pin/enterpin/IEnterPinView.kt @@ -1,4 +1,4 @@ -package dev.ragnarok.filegallery.fragment.enterpin +package dev.ragnarok.filegallery.fragment.pin.enterpin import dev.ragnarok.filegallery.fragment.base.core.IErrorView import dev.ragnarok.filegallery.fragment.base.core.IMvpView diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/listener/EndlessRecyclerOnScrollListener.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/listener/EndlessRecyclerOnScrollListener.kt index 98a965567..f0f5821fe 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/listener/EndlessRecyclerOnScrollListener.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/listener/EndlessRecyclerOnScrollListener.kt @@ -54,13 +54,13 @@ abstract class EndlessRecyclerOnScrollListener : RecyclerView.OnScrollListener { } } - is LinearLayoutManager -> { - isLastElementVisible = isAtLastElementOfLinearLayoutManager(manager) + is GridLayoutManager -> { + isLastElementVisible = isAtLastElementOfGridLayoutManager(manager) isFirstElementVisible = manager.findFirstVisibleItemPosition() == 0 } - is GridLayoutManager -> { - isLastElementVisible = isAtLastElementOfGridLayoutManager(manager) + is LinearLayoutManager -> { + isLastElementVisible = isAtLastElementOfLinearLayoutManager(manager) isFirstElementVisible = manager.findFirstVisibleItemPosition() == 0 } } diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/place/Place.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/place/Place.kt index 4f247209a..ba7c3e7a9 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/place/Place.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/place/Place.kt @@ -7,16 +7,11 @@ import android.os.Bundle import android.os.Parcel import android.os.Parcelable import androidx.activity.result.ActivityResultLauncher -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentManager -import androidx.fragment.app.FragmentResultListener open class Place : Parcelable { val type: Int var isNeedFinishMain = false private set - private var requestListenerKey: String? = null - private var requestListener: FragmentResultListener? = null private var activityResultLauncher: ActivityResultLauncher? = null private var args: Bundle? = null @@ -35,15 +30,6 @@ open class Place : Parcelable { } } - fun setFragmentListener( - requestListenerKey: String, - requestListener: FragmentResultListener - ): Place { - this.requestListenerKey = requestListenerKey - this.requestListener = requestListener - return this - } - fun setActivityResultLauncher(activityResultLauncher: ActivityResultLauncher): Place { this.activityResultLauncher = activityResultLauncher return this @@ -99,18 +85,6 @@ open class Place : Parcelable { return args ?: Bundle() } - fun applyFragmentListener(fragment: Fragment, fragmentManager: FragmentManager) { - requestListener?.let { - requestListenerKey?.let { it1 -> - fragmentManager.setFragmentResultListener( - it1, - fragment, - it - ) - } - } - } - fun launchActivityForResult(context: Activity, intent: Intent) { if (activityResultLauncher != null && !isNeedFinishMain) { activityResultLauncher?.launch(intent) diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/Json.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/Json.kt index 622660125..78ae4564a 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/Json.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/Json.kt @@ -86,15 +86,33 @@ sealed class Json( } } + /** + * Decodes and deserializes the given JSON [string] to the value of type [T] using deserializer + * retrieved from the reified type parameter. + * + * @throws SerializationException in case of any decoding-specific error + * @throws IllegalArgumentException if the decoded input is not a valid instance of [T] + */ + @OptIn(InternalSerializationApi::class) + inline fun decodeFromString( + @FormatLanguage( + "json", + "", + "" + ) string: String + ): T = + decodeFromString(serializersModule.serializer(), string) + /** * Deserializes the given JSON [string] into a value of type [T] using the given [deserializer]. * * @throws [SerializationException] if the given JSON string is not a valid JSON input for the type [T] * @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T] */ + @OptIn(InternalSerializationApi::class) final override fun decodeFromString( deserializer: DeserializationStrategy, - string: String + @FormatLanguage("json", "", "") string: String ): T { val lexer = StringJsonLexer(string) val input = StreamingJsonDecoder(this, WriteMode.OBJ, lexer, deserializer.descriptor, null) @@ -187,7 +205,7 @@ enum class DecodeSequenceMode { /** * Declares that parser itself should select between [WHITESPACE_SEPARATED] and [ARRAY_WRAPPED] modes. - * The selection is performed by looking on the first meaningful character of the stream. + * The selection is performed by looking at the first meaningful character of the stream. * * In most cases, auto-detection is sufficient to correctly parse an input. * If the input is _whitespace-separated stream of the arrays_, parser could select an incorrect mode, diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonContentPolymorphicSerializer.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonContentPolymorphicSerializer.kt index 3033d469b..4b59c73b0 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonContentPolymorphicSerializer.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonContentPolymorphicSerializer.kt @@ -60,11 +60,12 @@ import kotlin.reflect.KClass * * // Now both statements will yield different subclasses of Payment: * - * Json.parse(PaymentSerializer, """{"amount":"1.0","date":"03.02.2020"}""") - * Json.parse(PaymentSerializer, """{"amount":"2.0","date":"03.02.2020","reason":"complaint"}""") + * Json.decodeFromString(PaymentSerializer, """{"amount":"1.0","date":"03.02.2020"}""") + * Json.decodeFromString(PaymentSerializer, """{"amount":"2.0","date":"03.02.2020","reason":"complaint"}""") * ``` * - * @param T A root class for all classes that could be possibly encountered during serialization and deserialization. + * @param T A root type for all classes that could be possibly encountered during serialization and deserialization. + * Must be non-final class or interface. * @param baseClass A class token for [T]. */ @OptIn(ExperimentalSerializationApi::class) diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElement.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElement.kt index 33ebc087d..5947edf54 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElement.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElement.kt @@ -53,33 +53,58 @@ sealed class JsonPrimitive : JsonElement() { override fun toString(): String = content } -/** - * Creates [JsonPrimitive] from the given boolean. - */ +/** Creates a [JsonPrimitive] from the given boolean. */ fun JsonPrimitive(value: Boolean?): JsonPrimitive { if (value == null) return JsonNull return JsonLiteral(value, isString = false) } -/** - * Creates [JsonPrimitive] from the given number. - */ +/** Creates a [JsonPrimitive] from the given number. */ fun JsonPrimitive(value: Number?): JsonPrimitive { if (value == null) return JsonNull return JsonLiteral(value, isString = false) } /** - * Creates [JsonPrimitive] from the given string. + * Creates a numeric [JsonPrimitive] from the given [UByte]. + * + * The value will be encoded as a JSON number. + */ +@ExperimentalSerializationApi +fun JsonPrimitive(value: UByte): JsonPrimitive = JsonPrimitive(value.toULong()) + +/** + * Creates a numeric [JsonPrimitive] from the given [UShort]. + * + * The value will be encoded as a JSON number. + */ +@ExperimentalSerializationApi +fun JsonPrimitive(value: UShort): JsonPrimitive = JsonPrimitive(value.toULong()) + +/** + * Creates a numeric [JsonPrimitive] from the given [UInt]. + * + * The value will be encoded as a JSON number. + */ +@ExperimentalSerializationApi +fun JsonPrimitive(value: UInt): JsonPrimitive = JsonPrimitive(value.toULong()) + +/** + * Creates a numeric [JsonPrimitive] from the given [ULong]. + * + * The value will be encoded as a JSON number. */ +@SuppressAnimalSniffer // Long.toUnsignedString(long) +@ExperimentalSerializationApi +fun JsonPrimitive(value: ULong): JsonPrimitive = JsonUnquotedLiteral(value.toString()) + +/** Creates a [JsonPrimitive] from the given string. */ fun JsonPrimitive(value: String?): JsonPrimitive { if (value == null) return JsonNull return JsonLiteral(value, isString = true) } -/** - * Creates [JsonNull]. - */ +/** Creates [JsonNull]. */ @ExperimentalSerializationApi @Suppress("FunctionName", "UNUSED_PARAMETER") // allows to call `JsonPrimitive(null)` fun JsonPrimitive(value: Nothing?): JsonNull = JsonNull diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElementBuilders.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElementBuilders.kt index c01db300e..f27d5a939 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElementBuilders.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/JsonElementBuilders.kt @@ -147,6 +147,15 @@ class JsonArrayBuilder @PublishedApi internal constructor() { return true } + /** + * Adds the given JSON [elements] to a resulting JSON array. + * + * @return `true` if the list was changed as the result of the operation. + */ + @ExperimentalSerializationApi + fun addAll(elements: Collection): Boolean = + content.addAll(elements) + @PublishedApi internal fun build(): JsonArray = JsonArray(content) } @@ -197,6 +206,35 @@ fun JsonArrayBuilder.addJsonObject(builderAction: JsonObjectBuilder.() -> Unit): fun JsonArrayBuilder.addJsonArray(builderAction: JsonArrayBuilder.() -> Unit): Boolean = add(buildJsonArray(builderAction)) +/** + * Adds the given string [values] to a resulting JSON array. + * + * @return `true` if the list was changed as the result of the operation. + */ +@JvmName("addAllStrings") +@ExperimentalSerializationApi +fun JsonArrayBuilder.addAll(values: Collection): Boolean = + addAll(values.map(::JsonPrimitive)) + +/** + * Adds the given boolean [values] to a resulting JSON array. + * + * @return `true` if the list was changed as the result of the operation. + */ +@JvmName("addAllBooleans") +@ExperimentalSerializationApi +fun JsonArrayBuilder.addAll(values: Collection): Boolean = + addAll(values.map(::JsonPrimitive)) + +/** + * Adds the given numeric [values] to a resulting JSON array. + * + * @return `true` if the list was changed as the result of the operation. + */ +@JvmName("addAllNumbers") +@ExperimentalSerializationApi +fun JsonArrayBuilder.addAll(values: Collection): Boolean = + addAll(values.map(::JsonPrimitive)) @DslMarker internal annotation class JsonDslMarker diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/CharsetReader.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/CharsetReader.kt index 33d34e307..f10ffed6f 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/CharsetReader.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/CharsetReader.kt @@ -18,7 +18,20 @@ internal class CharsetReader( private var leftoverChar = 0.toChar() init { - byteBuffer.flip() // Make empty + // An explicit cast is needed here due to an API change in Java 9, see #2218. + // + // In Java 8 and earlier, the `flip` method was final in `Buffer`, and returned a `Buffer`. + // In Java 9 and later, the method was opened, and `ByteFuffer` overrides it, returning a `ByteBuffer`. + // + // You could observe this by decompiling this call with `javap`: + // Compiled with Java 8 it produces `INVOKEVIRTUAL java/nio/ByteBuffer.flip ()Ljava/nio/Buffer;` + // Compiled with Java 9+ it produces `INVOKEVIRTUAL java/nio/ByteBuffer.flip ()Ljava/nio/ByteBuffer;` + // + // This causes a `NoSuchMethodError` when running a class, compiled with a newer Java version, on Java 8. + // + // To mitigate that, `--bootclasspath` / `--release` options were introduced in `javac`, but there are no + // counterparts for these options in `kotlinc`, so an explicit cast is required. + (byteBuffer as Buffer).flip() // Make empty } @Suppress("NAME_SHADOWING") @@ -91,7 +104,7 @@ internal class CharsetReader( if (bytesRead < 0) return bytesRead byteBuffer.position(position + bytesRead) } finally { - byteBuffer.flip() + (byteBuffer as Buffer).flip() // see the `init` block in this class for the reasoning behind the cast } return byteBuffer.remaining() } diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/FormatLanguage.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/FormatLanguage.kt new file mode 100644 index 000000000..edbcf08cf --- /dev/null +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/FormatLanguage.kt @@ -0,0 +1,45 @@ +package dev.ragnarok.filegallery.util.serializeble.json.internal + +import kotlinx.serialization.InternalSerializationApi + +/** + * Multiplatform analogue of `org.intellij.lang.annotations.Language` annotation. + * + * An alias is used instead of class, because the actual class in the JVM will conflict with the class from the stdlib - + * we want to avoid the situation with different classes having the same fully-qualified name. + * [see](https://github.com/JetBrains/java-annotations/issues/34) + * + * Specifies that an element of the program represents a string that is a source code on a specified language. + * Code editors may use this annotation to enable syntax highlighting, code completion and other features + * inside the literals that assigned to the annotated variables, passed as arguments to the annotated parameters, + * or returned from the annotated methods. + *

+ * This annotation also could be used as a meta-annotation, to define derived annotations for convenience. + * E.g. the following annotation could be defined to annotate the strings that represent Java methods: + * + *

+ *   @Language(value = "JAVA", prefix = "class X{", suffix = "}")
+ *   @interface JavaMethod {}
+ * 
+ *

+ * Note that using the derived annotation as meta-annotation is not supported. + * Meta-annotation works only one level deep. + */ + +@InternalSerializationApi +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, + AnnotationTarget.FIELD, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.LOCAL_VARIABLE, + AnnotationTarget.ANNOTATION_CLASS +) +annotation class FormatLanguage( + val value: String, + // default parameters are not used due to https://youtrack.jetbrains.com/issue/KT-25946/ + val prefix: String, + val suffix: String, +) diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/JsonIterator.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/JsonIterator.kt index 53511f5e7..a1c5a8a77 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/JsonIterator.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/JsonIterator.kt @@ -73,6 +73,7 @@ private class JsonIteratorArrayWrapped( private val deserializer: DeserializationStrategy ) : Iterator { private var first = true + private var finished = false override fun next(): T { if (first) { @@ -88,7 +89,9 @@ private class JsonIteratorArrayWrapped( * Note: if array separator (comma) is missing, hasNext() returns true, but next() throws an exception. */ override fun hasNext(): Boolean { + if (finished) return false if (lexer.peekNextToken() == TC_END_LIST) { + finished = true lexer.consumeNextToken(TC_END_LIST) if (lexer.isNotEof()) { if (lexer.peekNextToken() == TC_BEGIN_LIST) lexer.fail( @@ -100,7 +103,7 @@ private class JsonIteratorArrayWrapped( } return false } - if (!lexer.isNotEof()) lexer.fail(TC_END_LIST) + if (!lexer.isNotEof() && !finished) lexer.fail(TC_END_LIST) return true } } diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/StreamingJsonDecoder.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/StreamingJsonDecoder.kt index 569467452..cdbbaacc1 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/StreamingJsonDecoder.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/StreamingJsonDecoder.kt @@ -98,6 +98,9 @@ internal open class StreamingJsonDecoder( return actualSerializer.deserialize(this) as T } catch (e: MissingFieldException) { + // Add "at path" if and only if we've just caught an exception and it hasn't been augmented yet + if (e.message?.contains("at path") == true) throw e + // NB: we could've use some additional flag marker or augment the stacktrace, but it seemed to be as too much of a burden throw MissingFieldException( e.missingFields, e.message + " at path: " + lexer.path.getPath(), diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonDecoder.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonDecoder.kt index 287f0487a..9c90de8a1 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonDecoder.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonDecoder.kt @@ -202,9 +202,14 @@ private sealed class AbstractJsonTreeDecoder( ), json ) else super.decodeTaggedInline(tag, inlineDescriptor) + + override fun decodeInline(descriptor: SerialDescriptor): Decoder { + return if (currentTagOrNull != null) super.decodeInline(descriptor) + else JsonPrimitiveDecoder(json, value).decodeInline(descriptor) + } } -private class JsonPrimitiveDecoder(json: Json, override val value: JsonPrimitive) : +private class JsonPrimitiveDecoder(json: Json, override val value: JsonElement) : AbstractJsonTreeDecoder(json, value) { init { diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonEncoder.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonEncoder.kt index 3997601de..c791cf428 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonEncoder.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/TreeJsonEncoder.kt @@ -29,7 +29,7 @@ fun Json.writeJson(value: T, serializer: SerializationStrategy): JsonElem @ExperimentalSerializationApi private sealed class AbstractJsonTreeEncoder( final override val json: Json, - private val nodeConsumer: (JsonElement) -> Unit + protected val nodeConsumer: (JsonElement) -> Unit ) : NamedValueEncoder(), JsonEncoder { final override val serializersModule: SerializersModule @@ -86,7 +86,6 @@ private sealed class AbstractJsonTreeEncoder( encodePolymorphically(serializer, value) { polymorphicDiscriminator = it } } else JsonPrimitiveEncoder(json, nodeConsumer).apply { encodeSerializableValue(serializer, value) - endEncode(serializer.descriptor) } } @@ -128,6 +127,11 @@ private sealed class AbstractJsonTreeEncoder( else -> super.encodeTaggedInline(tag, inlineDescriptor) } + override fun encodeInline(descriptor: SerialDescriptor): Encoder { + return if (currentTagOrNull != null) super.encodeInline(descriptor) + else JsonPrimitiveEncoder(json, nodeConsumer).encodeInline(descriptor) + } + @SuppressAnimalSniffer // Long(Integer).toUnsignedString(long) private fun inlineUnsignedNumberEncoder(tag: String) = object : AbstractEncoder() { override val serializersModule: SerializersModule = json.serializersModule @@ -197,6 +201,7 @@ private class JsonPrimitiveEncoder( require(key === PRIMITIVE_TAG) { "This output can only consume primitives with '$PRIMITIVE_TAG' tag" } require(content == null) { "Primitive element was already recorded. Does call to .encodeXxx happen more than once?" } content = element + nodeConsumer(element) } override fun getCurrent(): JsonElement = diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/lexer/JsonLexer.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/lexer/JsonLexer.kt index 28353d358..852f36fb7 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/lexer/JsonLexer.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/json/internal/lexer/JsonLexer.kt @@ -33,6 +33,9 @@ internal class ArrayAsSequence(private val buffer: CharArray) : CharSequence { fun trim(newSize: Int) { length = minOf(buffer.size, newSize) } + + // source.toString() is used in JsonDecodingException + override fun toString(): String = substring(0, length) } internal class ReaderJsonLexer( diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/MsgPackConfiguration.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/MsgPackConfiguration.kt index 30763e64f..c927b836a 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/MsgPackConfiguration.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/MsgPackConfiguration.kt @@ -35,7 +35,12 @@ data class MsgPackConfiguration( * Useful when only parts of data are of interest * false by default */ - val ignoreUnknownKeys: Boolean = true + val ignoreUnknownKeys: Boolean = true, + /** + * Encode enum values as Ints corresponding to their ordinal values + * false by default + */ + val ordinalEnums: Boolean = false ) { companion object { val default: MsgPackConfiguration = MsgPackConfiguration() diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt index c4c45d84a..0c96f4f46 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/extensions/BaseMsgPackExtensionSerializer.kt @@ -32,7 +32,7 @@ abstract class BaseMsgPackExtensionSerializer : KSerializer { extension.extTypeId ) } - encoder.encodeSerializableValue(serializer, serialize(value)) + encoder.encodeSerializableValue(serializer, extension) } abstract fun deserialize(extension: MsgPackExtension): T diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackDecoder.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackDecoder.kt index f6b318b90..770de0e72 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackDecoder.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackDecoder.kt @@ -117,6 +117,9 @@ internal class BasicMsgPackDecoder( } override fun decodeEnum(enumDescriptor: SerialDescriptor): Int { + if (configuration.ordinalEnums) { + return msgUnpacker.unpackInt(configuration.strictTypes, configuration.preventOverflows) + } return enumDescriptor.getElementIndex(decodeString()) } diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackEncoder.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackEncoder.kt index 6ec46b38a..ca21c347e 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackEncoder.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/util/serializeble/msgpack/internal/MsgPackEncoder.kt @@ -64,12 +64,16 @@ internal class BasicMsgPackEncoder( } override fun encodeEnum(enumDescriptor: SerialDescriptor, index: Int) { - result.addAll( - packer.packString( - enumDescriptor.getElementName(index), - configuration.rawCompatibility + if (configuration.ordinalEnums) { + result.addAll(packer.packInt(index, configuration.strictTypeWriting)) + } else { + result.addAll( + packer.packString( + enumDescriptor.getElementName(index), + configuration.rawCompatibility + ) ) - ) + } } fun encodeByteArray(value: ByteArray) { diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/view/RoundCornerLinearView.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/view/RoundCornerLinearView.kt index dab2fce69..c1d8d0cb1 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/view/RoundCornerLinearView.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/view/RoundCornerLinearView.kt @@ -64,39 +64,42 @@ class RoundCornerLinearView : LinearLayout { override fun onDraw(canvas: Canvas) { super.onDraw(canvas) + val widthTmp = width + val heightTmp = height + if (widthTmp <= 0 || heightTmp <= 0) { + return + } FILL_PAINT.color = color FILL_PAINT.shader = null - val width = width - val height = height PATH.reset() PATH.moveTo(0f, radius_top_left) PATH.arcTo(0f, 0f, 2 * radius_top_left, 2 * radius_top_left, 180f, 90f, false) - PATH.lineTo(width - radius_top_right, 0f) + PATH.lineTo(widthTmp - radius_top_right, 0f) PATH.arcTo( - width - 2 * radius_top_right, + widthTmp - 2 * radius_top_right, 0f, - width.toFloat(), + widthTmp.toFloat(), 2 * radius_top_right, 270f, 90f, false ) - PATH.lineTo(width.toFloat(), height - radius_bottom_right) + PATH.lineTo(widthTmp.toFloat(), heightTmp - radius_bottom_right) PATH.arcTo( - width - 2 * radius_bottom_right, - height - 2 * radius_bottom_right, - width.toFloat(), - height.toFloat(), + widthTmp - 2 * radius_bottom_right, + heightTmp - 2 * radius_bottom_right, + widthTmp.toFloat(), + heightTmp.toFloat(), 0f, 90f, false ) - PATH.lineTo(radius_bottom_left, height.toFloat()) + PATH.lineTo(radius_bottom_left, heightTmp.toFloat()) PATH.arcTo( 0f, - height - 2 * radius_bottom_left, + heightTmp - 2 * radius_bottom_left, 2 * radius_bottom_left, - height.toFloat(), + heightTmp.toFloat(), 90f, 90f, false diff --git a/build.gradle b/build.gradle index e6ac29ba2..9042bd015 100644 --- a/build.gradle +++ b/build.gradle @@ -24,24 +24,24 @@ buildscript { ext.concurentVersion = "1.2.0-alpha01" ext.constraintlayoutVersion = "2.2.0-alpha09" ext.coordinatorlayoutVersion = "1.2.0" - ext.coreVersion = "1.10.0" + ext.coreVersion = "1.10.1" ext.customviewVersion = "1.2.0-alpha02" ext.customviewPoolingcontainerVersion = "1.0.0" ext.drawerlayoutVersion = "1.2.0" ext.dynamicanimationVersion = "1.1.0-alpha03" ext.exifinterfaceVersion = "1.3.6" - ext.fragmentVersion = "1.6.0-beta01" + ext.fragmentVersion = "1.6.0-rc01" ext.lifecycleVersion = "2.6.1" ext.loaderVersion = "1.1.0" ext.mediaVersion = "1.7.0-alpha01" - ext.media3Version = "1.0.1" + ext.media3Version = "1.1.0-alpha01" ext.recyclerviewVersion = "1.3.0" ext.savedStateVersion = "1.2.1" ext.swiperefreshlayoutVersion = "1.2.0-alpha01" ext.tracingVersion = "1.2.0-beta04" ext.transitionVersion = "1.4.1" ext.vectordrawableVersion = "1.2.0-beta01" - ext.webkitVersion = "1.7.0-beta01" + ext.webkitVersion = "1.7.0-rc01" ext.workVersion = "2.8.1" //firebase libraries @@ -59,7 +59,7 @@ buildscript { //common libraries ext.kotlin_version = "1.8.21" ext.kotlin_coroutines = "1.7.0" - ext.kotlin_serializer = "1.5.0" + ext.kotlin_serializer = "1.5.1" ext.okhttpLibraryVersion = "5.0.0-alpha.11" ext.okioVersion = "3.3.0" ext.rxJavaVersion = "3.1.6" diff --git a/libfenrir/src/main/java/com/github/luben/zstd/Zstd.java b/libfenrir/src/main/java/com/github/luben/zstd/Zstd.java index 21e49eb18..a7f2a3920 100644 --- a/libfenrir/src/main/java/com/github/luben/zstd/Zstd.java +++ b/libfenrir/src/main/java/com/github/luben/zstd/Zstd.java @@ -507,6 +507,7 @@ public static long decompressDirectByteBufferFastDict(ByteBuffer dst, int dstOff public static native int setCompressionWorkers(long stream, int workers); public static native int setDecompressionLongMax(long stream, int windowLogMax); public static native int setDecompressionMagicless(long stream, boolean useMagicless); + public static native int setRefMultipleDDicts(long stream, boolean useMultiple); /* Utility methods */ diff --git a/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStream.java b/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStream.java index 6bc0fe09e..f3177318c 100644 --- a/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStream.java +++ b/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStream.java @@ -89,6 +89,17 @@ public ZstdInputStream setLongMax(int windowLogMax) throws IOException { return this; } + /** + * Enable or disable support for multiple dictionary references + * + * @param useMultiple Enables references table for DDict, so the DDict used for decompression will be + * determined per the dictId in the frame, default: false + */ + public ZstdInputStream setRefMultipleDDicts(boolean useMultiple) throws IOException { + inner.setRefMultipleDDicts(useMultiple); + return this; + } + public int read(byte[] dst, int offset, int len) throws IOException { return inner.read(dst, offset, len); } diff --git a/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStreamNoFinalizer.java b/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStreamNoFinalizer.java index 74ac1f113..9934ad8bd 100644 --- a/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStreamNoFinalizer.java +++ b/libfenrir/src/main/java/com/github/luben/zstd/ZstdInputStreamNoFinalizer.java @@ -110,6 +110,14 @@ public synchronized ZstdInputStreamNoFinalizer setLongMax(int windowLogMax) thro return this; } + public synchronized ZstdInputStreamNoFinalizer setRefMultipleDDicts(boolean useMultiple) throws IOException { + int size = Zstd.setRefMultipleDDicts(stream, useMultiple); + if (Zstd.isError(size)) { + throw new ZstdIOException(size); + } + return this; + } + public synchronized int read(byte[] dst, int offset, int len) throws IOException { // guard agains buffer overflows if (offset < 0 || len > dst.length - offset) { diff --git a/libfenrir/src/main/jni/CMakeLists.txt b/libfenrir/src/main/jni/CMakeLists.txt index 1bba3bf3d..0b77cbd51 100644 --- a/libfenrir/src/main/jni/CMakeLists.txt +++ b/libfenrir/src/main/jni/CMakeLists.txt @@ -72,7 +72,7 @@ add_library(thorvg STATIC thorvg/src/loaders/svg/tvgXmlParser.cpp) target_compile_options(thorvg PRIVATE - -fno-exceptions -ffast-math ${OPTIMIZE_NORMAL} -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables -Woverloaded-virtual -Wno-unused-parameter ${SYM_VISIBILITY}) + -DTVG_STATIC=1 -fno-exceptions -ffast-math ${OPTIMIZE_NORMAL} -fno-rtti -fno-unwind-tables -fno-asynchronous-unwind-tables -Woverloaded-virtual -Wno-unused-parameter ${SYM_VISIBILITY}) target_include_directories(thorvg PRIVATE thorvg/inc thorvg/src/lib diff --git a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/convert.h b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/convert.h index 2f1ce4214..4f6d2536e 100644 --- a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/convert.h +++ b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/convert.h @@ -751,6 +751,21 @@ int ARGBToI420(const uint8_t* src_argb, int width, int height); +// Convert ARGB to I420 with Alpha +LIBYUV_API +int ARGBToI420Alpha(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_u, + int dst_stride_u, + uint8_t* dst_v, + int dst_stride_v, + uint8_t* dst_a, + int dst_stride_a, + int width, + int height); + // BGRA little endian (argb in memory) to I420. LIBYUV_API int BGRAToI420(const uint8_t* src_bgra, diff --git a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/row.h b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/row.h index 6e973bcfe..c47c55d15 100644 --- a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/row.h +++ b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/row.h @@ -657,13 +657,24 @@ extern "C" { #define HAS_ARGBSETROW_LSX #define HAS_ARGBTOUVJROW_LSX #define HAS_ARGBTOYJROW_LSX +#define HAS_ARGBMIRRORROW_LSX #define HAS_BGRATOUVROW_LSX #define HAS_BGRATOYROW_LSX #define HAS_I400TOARGBROW_LSX #define HAS_I444TOARGBROW_LSX #define HAS_INTERPOLATEROW_LSX +#define HAS_I422ALPHATOARGBROW_LSX +#define HAS_I422TOARGB1555ROW_LSX +#define HAS_I422TOARGB4444ROW_LSX +#define HAS_I422TORGB24ROW_LSX +#define HAS_I422TORGB565ROW_LSX +#define HAS_I422TORGBAROW_LSX +#define HAS_I422TOUYVYROW_LSX +#define HAS_I422TOYUY2ROW_LSX #define HAS_J400TOARGBROW_LSX #define HAS_MERGEUVROW_LSX +#define HAS_MIRRORROW_LSX +#define HAS_MIRRORUVROW_LSX #define HAS_MIRRORSPLITUVROW_LSX #define HAS_NV12TOARGBROW_LSX #define HAS_NV12TORGB565ROW_LSX @@ -687,6 +698,9 @@ extern "C" { #define HAS_SPLITUVROW_LSX #define HAS_UYVYTOARGBROW_LSX #define HAS_YUY2TOARGBROW_LSX +#define HAS_YUY2TOUVROW_LSX +#define HAS_YUY2TOUV422ROW_LSX +#define HAS_YUY2TOYROW_LSX #define HAS_ARGBTOYROW_LSX #define HAS_ABGRTOYJROW_LSX #define HAS_RGBATOYJROW_LSX @@ -694,6 +708,10 @@ extern "C" { #define HAS_RAWTOYJROW_LSX #endif +#if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx) +#define HAS_I422TOARGBROW_LSX +#endif + #if !defined(LIBYUV_DISABLE_LASX) && defined(__loongarch_asx) #define HAS_ARGB1555TOARGBROW_LASX #define HAS_ARGB1555TOUVROW_LASX @@ -760,20 +778,39 @@ extern "C" { #if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector) #define HAS_AB64TOARGBROW_RVV #define HAS_AR64TOARGBROW_RVV +#define HAS_ARGBATTENUATEROW_RVV #define HAS_ARGBTOAB64ROW_RVV #define HAS_ARGBTOAR64ROW_RVV #define HAS_ARGBTORAWROW_RVV #define HAS_ARGBTORGB24ROW_RVV +#define HAS_ARGBTOYROW_RVV +#define HAS_ARGBTOYJROW_RVV +#define HAS_ABGRTOYROW_RVV +#define HAS_ABGRTOYJROW_RVV +#define HAS_BGRATOYROW_RVV +#define HAS_I422ALPHATOARGBROW_RVV +#define HAS_I422TOARGBROW_RVV +#define HAS_I422TORGB24ROW_RVV +#define HAS_I422TORGBAROW_RVV +#define HAS_I444ALPHATOARGBROW_RVV +#define HAS_I444TOARGBROW_RVV +#define HAS_I444TORGB24ROW_RVV #define HAS_MERGEARGBROW_RVV #define HAS_MERGERGBROW_RVV #define HAS_MERGEXRGBROW_RVV -#define HAS_SPLITARGBROW_RVV -#define HAS_SPLITRGBROW_RVV -#define HAS_SPLITXRGBROW_RVV #define HAS_RAWTOARGBROW_RVV #define HAS_RAWTORGB24ROW_RVV #define HAS_RAWTORGBAROW_RVV +#define HAS_RAWTOYJROW_RVV +#define HAS_RAWTOYROW_RVV #define HAS_RGB24TOARGBROW_RVV +#define HAS_RGB24TOYJROW_RVV +#define HAS_RGB24TOYROW_RVV +#define HAS_RGBATOYROW_RVV +#define HAS_RGBATOYJROW_RVV +#define HAS_SPLITARGBROW_RVV +#define HAS_SPLITRGBROW_RVV +#define HAS_SPLITXRGBROW_RVV #endif #if defined(_MSC_VER) && !defined(__CLR_VER) && !defined(__clang__) @@ -835,8 +872,8 @@ typedef uint32_t ulvec32[8]; typedef uint8_t ulvec8[32]; #endif -#if defined(__aarch64__) || defined(__arm__) -// This struct is for ARM color conversion. +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv) +// This struct is for ARM and RISC-V color conversion. struct YuvConstants { uvec8 kUVCoeff; vec16 kRGBCoeffBias; @@ -1041,6 +1078,50 @@ void UYVYToARGBRow_NEON(const uint8_t* src_uyvy, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width); +void I444ToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I444AlphaToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I444ToRGB24Row_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width); +void I422ToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I422AlphaToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); +void I422ToRGBARow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgba, + const struct YuvConstants* yuvconstants, + int width); +void I422ToRGB24Row_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width); void I444ToARGBRow_MSA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1060,6 +1141,12 @@ void I422ToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width); +void I422ToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGBRow_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1072,6 +1159,12 @@ void I422ToRGBARow_MSA(const uint8_t* src_y, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width); +void I422ToRGBARow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGBARow_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1085,6 +1178,13 @@ void I422AlphaToARGBRow_MSA(const uint8_t* src_y, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width); +void I422AlphaToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); void I422AlphaToARGBRow_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1098,6 +1198,12 @@ void I422ToRGB24Row_MSA(const uint8_t* src_y, uint8_t* dst_argb, const struct YuvConstants* yuvconstants, int width); +void I422ToRGB24Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGB24Row_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1110,6 +1216,12 @@ void I422ToRGB565Row_MSA(const uint8_t* src_y, uint8_t* dst_rgb565, const struct YuvConstants* yuvconstants, int width); +void I422ToRGB565Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb565, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGB565Row_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1122,6 +1234,12 @@ void I422ToARGB4444Row_MSA(const uint8_t* src_y, uint8_t* dst_argb4444, const struct YuvConstants* yuvconstants, int width); +void I422ToARGB4444Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb4444, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGB4444Row_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1134,6 +1252,12 @@ void I422ToARGB1555Row_MSA(const uint8_t* src_y, uint8_t* dst_argb1555, const struct YuvConstants* yuvconstants, int width); +void I422ToARGB1555Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb1555, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGB1555Row_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -1231,6 +1355,10 @@ void ARGBToYRow_NEON(const uint8_t* src_argb, uint8_t* dst_y, int width); void ARGBToYJRow_NEON(const uint8_t* src_argb, uint8_t* dst_yj, int width); void ABGRToYJRow_NEON(const uint8_t* src_abgr, uint8_t* dst_yj, int width); void RGBAToYJRow_NEON(const uint8_t* src_rgba, uint8_t* dst_yj, int width); +void ARGBToYRow_RVV(const uint8_t* src_argb, uint8_t* dst_y, int width); +void ARGBToYJRow_RVV(const uint8_t* src_argb, uint8_t* dst_yj, int width); +void ABGRToYJRow_RVV(const uint8_t* src_rgba, uint8_t* dst_yj, int width); +void RGBAToYJRow_RVV(const uint8_t* src_rgba, uint8_t* dst_yj, int width); void ARGBToYRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); void ARGBToYJRow_MSA(const uint8_t* src_argb0, uint8_t* dst_y, int width); void ARGBToYRow_LSX(const uint8_t* src_argb0, uint8_t* dst_y, int width); @@ -1452,6 +1580,13 @@ void ARGB1555ToYRow_NEON(const uint8_t* src_argb1555, void ARGB4444ToYRow_NEON(const uint8_t* src_argb4444, uint8_t* dst_y, int width); +void BGRAToYRow_RVV(const uint8_t* src_bgra, uint8_t* dst_y, int width); +void ABGRToYRow_RVV(const uint8_t* src_abgr, uint8_t* dst_y, int width); +void RGBAToYRow_RVV(const uint8_t* src_rgba, uint8_t* dst_y, int width); +void RGB24ToYRow_RVV(const uint8_t* src_rgb24, uint8_t* dst_y, int width); +void RGB24ToYJRow_RVV(const uint8_t* src_rgb24, uint8_t* dst_yj, int width); +void RAWToYRow_RVV(const uint8_t* src_raw, uint8_t* dst_y, int width); +void RAWToYJRow_RVV(const uint8_t* src_raw, uint8_t* dst_yj, int width); void BGRAToYRow_MSA(const uint8_t* src_argb, uint8_t* dst_y, int width); void ABGRToYRow_MSA(const uint8_t* src_argb, uint8_t* dst_y, int width); void RGBAToYRow_MSA(const uint8_t* src_argb, uint8_t* dst_y, int width); @@ -1958,6 +2093,7 @@ void MirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_SSSE3(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_NEON(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); +void MirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_LASX(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_C(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); @@ -1965,17 +2101,20 @@ void MirrorRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_SSE2(const uint8_t* src, uint8_t* dst, int width); void MirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorRow_Any_LSX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorRow_Any_LASX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorUVRow_AVX2(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_SSSE3(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_NEON(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_MSA(const uint8_t* src_uv, uint8_t* dst_uv, int width); +void MirrorUVRow_LSX(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_LASX(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_C(const uint8_t* src_uv, uint8_t* dst_uv, int width); void MirrorUVRow_Any_AVX2(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorUVRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorUVRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorUVRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void MirrorUVRow_Any_LSX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorUVRow_Any_LASX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void MirrorSplitUVRow_SSSE3(const uint8_t* src, @@ -2005,6 +2144,7 @@ void ARGBMirrorRow_AVX2(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_SSE2(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_NEON(const uint8_t* src_argb, uint8_t* dst_argb, int width); void ARGBMirrorRow_MSA(const uint8_t* src, uint8_t* dst, int width); +void ARGBMirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_LASX(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_C(const uint8_t* src, uint8_t* dst, int width); void ARGBMirrorRow_Any_AVX2(const uint8_t* src_ptr, @@ -2017,6 +2157,7 @@ void ARGBMirrorRow_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBMirrorRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void ARGBMirrorRow_Any_LSX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void ARGBMirrorRow_Any_LASX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); @@ -4731,6 +4872,12 @@ void I422ToARGBRow_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToARGBRow_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGBRow_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4743,6 +4890,12 @@ void I422ToRGBARow_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToRGBARow_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGBARow_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4756,6 +4909,13 @@ void I422AlphaToARGBRow_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422AlphaToARGBRow_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + const uint8_t* a_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422AlphaToARGBRow_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4769,6 +4929,12 @@ void I422ToRGB24Row_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToRGB24Row_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGB24Row_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4781,6 +4947,12 @@ void I422ToRGB565Row_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToRGB565Row_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToRGB565Row_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4793,6 +4965,12 @@ void I422ToARGB4444Row_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToARGB4444Row_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGB4444Row_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4805,6 +4983,12 @@ void I422ToARGB1555Row_Any_MSA(const uint8_t* y_buf, uint8_t* dst_ptr, const struct YuvConstants* yuvconstants, int width); +void I422ToARGB1555Row_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + const struct YuvConstants* yuvconstants, + int width); void I422ToARGB1555Row_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -4917,12 +5101,18 @@ void YUY2ToUV422Row_NEON(const uint8_t* src_yuy2, uint8_t* dst_v, int width); void YUY2ToYRow_MSA(const uint8_t* src_yuy2, uint8_t* dst_y, int width); +void YUY2ToYRow_LSX(const uint8_t* src_yuy2, uint8_t* dst_y, int width); void YUY2ToYRow_LASX(const uint8_t* src_yuy2, uint8_t* dst_y, int width); void YUY2ToUVRow_MSA(const uint8_t* src_yuy2, int src_stride_yuy2, uint8_t* dst_u, uint8_t* dst_v, int width); +void YUY2ToUVRow_LSX(const uint8_t* src_yuy2, + int src_stride_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void YUY2ToUVRow_LASX(const uint8_t* src_yuy2, int src_stride_yuy2, uint8_t* dst_u, @@ -4932,6 +5122,10 @@ void YUY2ToUV422Row_MSA(const uint8_t* src_yuy2, uint8_t* dst_u, uint8_t* dst_v, int width); +void YUY2ToUV422Row_LSX(const uint8_t* src_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void YUY2ToUV422Row_LASX(const uint8_t* src_yuy2, uint8_t* dst_u, uint8_t* dst_v, @@ -4993,12 +5187,18 @@ void YUY2ToUV422Row_Any_NEON(const uint8_t* src_ptr, uint8_t* dst_v, int width); void YUY2ToYRow_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); +void YUY2ToYRow_Any_LSX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void YUY2ToYRow_Any_LASX(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); void YUY2ToUVRow_Any_MSA(const uint8_t* src_ptr, int src_stride_ptr, uint8_t* dst_u, uint8_t* dst_v, int width); +void YUY2ToUVRow_Any_LSX(const uint8_t* src_ptr, + int src_stride_ptr, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void YUY2ToUVRow_Any_LASX(const uint8_t* src_ptr, int src_stride_ptr, uint8_t* dst_u, @@ -5008,6 +5208,10 @@ void YUY2ToUV422Row_Any_MSA(const uint8_t* src_ptr, uint8_t* dst_u, uint8_t* dst_v, int width); +void YUY2ToUV422Row_Any_LSX(const uint8_t* src_ptr, + uint8_t* dst_u, + uint8_t* dst_v, + int width); void YUY2ToUV422Row_Any_LASX(const uint8_t* src_ptr, uint8_t* dst_u, uint8_t* dst_v, @@ -5243,6 +5447,11 @@ void I422ToYUY2Row_MSA(const uint8_t* src_y, const uint8_t* src_v, uint8_t* dst_yuy2, int width); +void I422ToYUY2Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_yuy2, + int width); void I422ToYUY2Row_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -5253,6 +5462,11 @@ void I422ToUYVYRow_MSA(const uint8_t* src_y, const uint8_t* src_v, uint8_t* dst_uyvy, int width); +void I422ToUYVYRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_uyvy, + int width); void I422ToUYVYRow_LASX(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, @@ -5263,6 +5477,11 @@ void I422ToYUY2Row_Any_MSA(const uint8_t* y_buf, const uint8_t* v_buf, uint8_t* dst_ptr, int width); +void I422ToYUY2Row_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + int width); void I422ToYUY2Row_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -5273,6 +5492,11 @@ void I422ToUYVYRow_Any_MSA(const uint8_t* y_buf, const uint8_t* v_buf, uint8_t* dst_ptr, int width); +void I422ToUYVYRow_Any_LSX(const uint8_t* y_buf, + const uint8_t* u_buf, + const uint8_t* v_buf, + uint8_t* dst_ptr, + int width); void I422ToUYVYRow_Any_LASX(const uint8_t* y_buf, const uint8_t* u_buf, const uint8_t* v_buf, @@ -5296,6 +5520,9 @@ void ARGBAttenuateRow_MSA(const uint8_t* src_argb, void ARGBAttenuateRow_LASX(const uint8_t* src_argb, uint8_t* dst_argb, int width); +void ARGBAttenuateRow_RVV(const uint8_t* src_argb, + uint8_t* dst_argb, + int width); void ARGBAttenuateRow_Any_SSSE3(const uint8_t* src_ptr, uint8_t* dst_ptr, int width); diff --git a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/version.h b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/version.h index 7f41b76cf..9568200e8 100644 --- a/libfenrir/src/main/jni/animation/libyuv/include/libyuv/version.h +++ b/libfenrir/src/main/jni/animation/libyuv/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1867 +#define LIBYUV_VERSION 1869 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/libfenrir/src/main/jni/animation/libyuv/source/convert.cc b/libfenrir/src/main/jni/animation/libyuv/source/convert.cc index 0bcfbf20b..301133897 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/convert.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/convert.cc @@ -1457,6 +1457,16 @@ int YUY2ToI420(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_LSX) && defined(HAS_YUY2TOUVROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + YUY2ToYRow = YUY2ToYRow_Any_LSX; + YUY2ToUVRow = YUY2ToUVRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + YUY2ToYRow = YUY2ToYRow_LSX; + YUY2ToUVRow = YUY2ToUVRow_LSX; + } + } +#endif #if defined(HAS_YUY2TOYROW_LASX) && defined(HAS_YUY2TOUVROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { YUY2ToYRow = YUY2ToYRow_Any_LASX; @@ -1835,6 +1845,192 @@ int ARGBToI420(const uint8_t* src_argb, return 0; } +#ifdef USE_EXTRACTALPHA +// Convert ARGB to I420 with Alpha +// The following version calls ARGBExtractAlpha on the full image. +LIBYUV_API +int ARGBToI420Alpha(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_u, + int dst_stride_u, + uint8_t* dst_v, + int dst_stride_v, + uint8_t* dst_a, + int dst_stride_a, + int width, + int height) { + int r = ARGBToI420(src_argb, src_stride_argb, dst_y, dst_stride_y, dst_u, + dst_stride_u, dst_v, dst_stride_v, width, height); + if (r == 0) { + r = ARGBExtractAlpha(src_argb, src_stride_argb, dst_a, dst_stride_a, width, + height); + } + return r; +} +#else // USE_EXTRACTALPHA +// Convert ARGB to I420 with Alpha +LIBYUV_API +int ARGBToI420Alpha(const uint8_t* src_argb, + int src_stride_argb, + uint8_t* dst_y, + int dst_stride_y, + uint8_t* dst_u, + int dst_stride_u, + uint8_t* dst_v, + int dst_stride_v, + uint8_t* dst_a, + int dst_stride_a, + int width, + int height) { + int y; + void (*ARGBToUVRow)(const uint8_t* src_argb0, int src_stride_argb, + uint8_t* dst_u, uint8_t* dst_v, int width) = + ARGBToUVRow_C; + void (*ARGBToYRow)(const uint8_t* src_argb, uint8_t* dst_y, int width) = + ARGBToYRow_C; + void (*ARGBExtractAlphaRow)(const uint8_t* src_argb, uint8_t* dst_a, + int width) = ARGBExtractAlphaRow_C; + if (!src_argb || !dst_y || !dst_u || !dst_v || !dst_a || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_argb = src_argb + (height - 1) * src_stride_argb; + src_stride_argb = -src_stride_argb; + } +#if defined(HAS_ARGBTOYROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToYRow = ARGBToYRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOUVROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBToUVRow = ARGBToUVRow_Any_NEON; + if (IS_ALIGNED(width, 16)) { + ARGBToUVRow = ARGBToUVRow_NEON; + } + } +#endif +#if defined(HAS_ARGBTOYROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToYRow = ARGBToYRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOUVROW_SSSE3) + if (TestCpuFlag(kCpuHasSSSE3)) { + ARGBToUVRow = ARGBToUVRow_Any_SSSE3; + if (IS_ALIGNED(width, 16)) { + ARGBToUVRow = ARGBToUVRow_SSSE3; + } + } +#endif +#if defined(HAS_ARGBTOYROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToYRow = ARGBToYRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToYRow = ARGBToYRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOUVROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBToUVRow = ARGBToUVRow_Any_AVX2; + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_AVX2; + } + } +#endif +#if defined(HAS_ARGBTOYROW_MSA) && defined(HAS_ARGBTOUVROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBToYRow = ARGBToYRow_Any_MSA; + ARGBToUVRow = ARGBToUVRow_Any_MSA; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_MSA; + } + if (IS_ALIGNED(width, 32)) { + ARGBToUVRow = ARGBToUVRow_MSA; + } + } +#endif +#if defined(HAS_ARGBTOYROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBToYRow = ARGBToYRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + ARGBToYRow = ARGBToYRow_LSX; + } + } +#endif +#if defined(HAS_ARGBTOYROW_LASX) && defined(HAS_ARGBTOUVROW_LASX) + if (TestCpuFlag(kCpuHasLASX)) { + ARGBToYRow = ARGBToYRow_Any_LASX; + ARGBToUVRow = ARGBToUVRow_Any_LASX; + if (IS_ALIGNED(width, 32)) { + ARGBToYRow = ARGBToYRow_LASX; + ARGBToUVRow = ARGBToUVRow_LASX; + } + } +#endif +#if defined(HAS_ARGBEXTRACTALPHAROW_SSE2) + if (TestCpuFlag(kCpuHasSSE2)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 8) ? ARGBExtractAlphaRow_SSE2 + : ARGBExtractAlphaRow_Any_SSE2; + } +#endif +#if defined(HAS_ARGBEXTRACTALPHAROW_AVX2) + if (TestCpuFlag(kCpuHasAVX2)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 32) ? ARGBExtractAlphaRow_AVX2 + : ARGBExtractAlphaRow_Any_AVX2; + } +#endif +#if defined(HAS_ARGBEXTRACTALPHAROW_NEON) + if (TestCpuFlag(kCpuHasNEON)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_NEON + : ARGBExtractAlphaRow_Any_NEON; + } +#endif +#if defined(HAS_ARGBEXTRACTALPHAROW_MSA) + if (TestCpuFlag(kCpuHasMSA)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_MSA + : ARGBExtractAlphaRow_Any_MSA; + } +#endif +#if defined(HAS_ARGBEXTRACTALPHAROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBExtractAlphaRow = IS_ALIGNED(width, 16) ? ARGBExtractAlphaRow_LSX + : ARGBExtractAlphaRow_Any_LSX; + } +#endif + + for (y = 0; y < height - 1; y += 2) { + ARGBToUVRow(src_argb, src_stride_argb, dst_u, dst_v, width); + ARGBToYRow(src_argb, dst_y, width); + ARGBToYRow(src_argb + src_stride_argb, dst_y + dst_stride_y, width); + ARGBExtractAlphaRow(src_argb, dst_a, width); + ARGBExtractAlphaRow(src_argb + src_stride_argb, dst_a + dst_stride_a, width); + src_argb += src_stride_argb * 2; + dst_y += dst_stride_y * 2; + dst_u += dst_stride_u; + dst_v += dst_stride_v; + dst_a += dst_stride_a * 2; + } + if (height & 1) { + ARGBToUVRow(src_argb, 0, dst_u, dst_v, width); + ARGBToYRow(src_argb, dst_y, width); + ARGBExtractAlphaRow(src_argb, dst_a, width); + } + return 0; +} +#endif // USE_EXTRACTALPHA + // Convert BGRA to I420. LIBYUV_API int BGRAToI420(const uint8_t* src_bgra, @@ -1940,6 +2136,11 @@ int BGRAToI420(const uint8_t* src_bgra, } } #endif +#if defined(HAS_BGRATOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + BGRAToYRow = BGRAToYRow_RVV; + } +#endif for (y = 0; y < height - 1; y += 2) { BGRAToUVRow(src_bgra, src_stride_bgra, dst_u, dst_v, width); @@ -2060,6 +2261,11 @@ int ABGRToI420(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYRow = ABGRToYRow_RVV; + } +#endif for (y = 0; y < height - 1; y += 2) { ABGRToUVRow(src_abgr, src_stride_abgr, dst_u, dst_v, width); @@ -2164,6 +2370,11 @@ int RGBAToI420(const uint8_t* src_rgba, } } #endif +#if defined(HAS_RGBATOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RGBAToYRow = RGBAToYRow_RVV; + } +#endif for (y = 0; y < height - 1; y += 2) { RGBAToUVRow(src_rgba, src_stride_rgba, dst_u, dst_v, width); @@ -2183,7 +2394,7 @@ int RGBAToI420(const uint8_t* src_rgba, // Enabled if 1 pass is available #if (defined(HAS_RGB24TOYROW_NEON) || defined(HAS_RGB24TOYROW_MSA) || \ - defined(HAS_RGB24TOYROW_LSX)) + defined(HAS_RGB24TOYROW_LSX) || defined(HAS_RGB24TOYROW_RVV)) #define HAS_RGB24TOYROW #endif @@ -2268,6 +2479,11 @@ int RGB24ToI420(const uint8_t* src_rgb24, } } #endif +#if defined(HAS_RGB24TOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RGB24ToYRow = RGB24ToYRow_RVV; + } +#endif // Other platforms do intermediate conversion from RGB24 to ARGB. #else // HAS_RGB24TOYROW @@ -2357,7 +2573,8 @@ int RGB24ToI420(const uint8_t* src_rgb24, #undef HAS_RGB24TOYROW // Enabled if 1 pass is available -#if defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) +#if defined(HAS_RGB24TOYJROW_NEON) || defined(HAS_RGB24TOYJROW_MSA) || \ + defined(HAS_RGB24TOYJROW_RVV) #define HAS_RGB24TOYJROW #endif @@ -2438,6 +2655,11 @@ int RGB24ToJ420(const uint8_t* src_rgb24, } } #endif +#if defined(HAS_RGB24TOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RGB24ToYJRow = RGB24ToYJRow_RVV; + } +#endif // Other platforms do intermediate conversion from RGB24 to ARGB. #else // HAS_RGB24TOYJROW @@ -2528,7 +2750,7 @@ int RGB24ToJ420(const uint8_t* src_rgb24, // Enabled if 1 pass is available #if (defined(HAS_RAWTOYROW_NEON) || defined(HAS_RAWTOYROW_MSA) || \ - defined(HAS_RAWTOYROW_LSX)) + defined(HAS_RAWTOYROW_LSX) || defined(HAS_RAWTOYROW_RVV)) #define HAS_RAWTOYROW #endif @@ -2612,6 +2834,11 @@ int RAWToI420(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RAWToYRow = RAWToYRow_RVV; + } +#endif // Other platforms do intermediate conversion from RAW to ARGB. #else // HAS_RAWTOYROW @@ -2701,7 +2928,8 @@ int RAWToI420(const uint8_t* src_raw, #undef HAS_RAWTOYROW // Enabled if 1 pass is available -#if defined(HAS_RAWTOYJROW_NEON) || defined(HAS_RAWTOYJROW_MSA) +#if defined(HAS_RAWTOYJROW_NEON) || defined(HAS_RAWTOYJROW_MSA) || \ + defined(HAS_RAWTOYJROW_RVV) #define HAS_RAWTOYJROW #endif @@ -2782,6 +3010,11 @@ int RAWToJ420(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RAWToYJRow = RAWToYJRow_RVV; + } +#endif // Other platforms do intermediate conversion from RAW to ARGB. #else // HAS_RAWTOYJROW @@ -3505,6 +3738,11 @@ int RGB24ToJ400(const uint8_t* src_rgb24, } } #endif +#if defined(HAS_RGB24TOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RGB24ToYJRow = RGB24ToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { RGB24ToYJRow(src_rgb24, dst_yj, width); @@ -3589,6 +3827,11 @@ int RAWToJ400(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RAWToYJRow = RAWToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { RAWToYJRow(src_raw, dst_yj, width); diff --git a/libfenrir/src/main/jni/animation/libyuv/source/convert_argb.cc b/libfenrir/src/main/jni/animation/libyuv/source/convert_argb.cc index c797a756b..4dfc5ecf2 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/convert_argb.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/convert_argb.cc @@ -120,6 +120,14 @@ int I420ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGBRow = I422ToARGBRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToARGBRow = I422ToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422TOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGBRow = I422ToARGBRow_Any_LASX; @@ -128,6 +136,11 @@ int I420ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToARGBRow = I422ToARGBRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -361,6 +374,14 @@ int I422ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGBRow = I422ToARGBRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToARGBRow = I422ToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422TOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGBRow = I422ToARGBRow_Any_LASX; @@ -369,6 +390,11 @@ int I422ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToARGBRow = I422ToARGBRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -599,6 +625,11 @@ int I444ToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToARGBRow = I444ToARGBRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I444ToARGBRow(src_y, src_u, src_v, dst_argb, yuvconstants, width); @@ -829,6 +860,11 @@ int I444ToRGB24Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TORGB24ROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToRGB24Row = I444ToRGB24Row_RVV; + } +#endif for (y = 0; y < height; ++y) { I444ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); @@ -2007,6 +2043,14 @@ int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422ALPHATOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422ALPHATOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422AlphaToARGBRow = I422AlphaToARGBRow_Any_LASX; @@ -2015,6 +2059,11 @@ int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422ALPHATOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -2047,6 +2096,11 @@ int I420AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -2132,6 +2186,14 @@ int I422AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422ALPHATOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422ALPHATOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422AlphaToARGBRow = I422AlphaToARGBRow_Any_LASX; @@ -2140,6 +2202,11 @@ int I422AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422ALPHATOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422AlphaToARGBRow = I422AlphaToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -2172,6 +2239,11 @@ int I422AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -2255,6 +2327,11 @@ int I444AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I444ALPHATOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444AlphaToARGBRow = I444AlphaToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -2287,6 +2364,11 @@ int I444AlphaToARGBMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I444AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -2515,6 +2597,11 @@ int I010AlphaToARGBMatrix(const uint16_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I210AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -2616,6 +2703,11 @@ int I210AlphaToARGBMatrix(const uint16_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I210AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -2715,6 +2807,11 @@ int I410AlphaToARGBMatrix(const uint16_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { I410AlphaToARGBRow(src_y, src_u, src_v, src_a, dst_argb, yuvconstants, @@ -4463,6 +4560,14 @@ int I422ToRGBAMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGBAROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGBARow = I422ToRGBARow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGBARow = I422ToRGBARow_LSX; + } + } +#endif #if defined(HAS_I422TORGBAROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGBARow = I422ToRGBARow_Any_LASX; @@ -4471,6 +4576,11 @@ int I422ToRGBAMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGBAROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToRGBARow = I422ToRGBARow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); @@ -4678,6 +4788,14 @@ int I420ToRGBAMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGBAROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGBARow = I422ToRGBARow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGBARow = I422ToRGBARow_LSX; + } + } +#endif #if defined(HAS_I422TORGBAROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGBARow = I422ToRGBARow_Any_LASX; @@ -4686,6 +4804,11 @@ int I420ToRGBAMatrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGBAROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToRGBARow = I422ToRGBARow_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToRGBARow(src_y, src_u, src_v, dst_rgba, yuvconstants, width); @@ -4795,6 +4918,14 @@ int I420ToRGB24Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB24ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGB24Row = I422ToRGB24Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGB24Row = I422ToRGB24Row_LSX; + } + } +#endif #if defined(HAS_I422TORGB24ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGB24Row = I422ToRGB24Row_Any_LASX; @@ -4803,6 +4934,11 @@ int I420ToRGB24Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB24ROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToRGB24Row = I422ToRGB24Row_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); @@ -4984,6 +5120,14 @@ int I422ToRGB24Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB24ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGB24Row = I422ToRGB24Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGB24Row = I422ToRGB24Row_LSX; + } + } +#endif #if defined(HAS_I422TORGB24ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGB24Row = I422ToRGB24Row_Any_LASX; @@ -4992,6 +5136,11 @@ int I422ToRGB24Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB24ROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToRGB24Row = I422ToRGB24Row_RVV; + } +#endif for (y = 0; y < height; ++y) { I422ToRGB24Row(src_y, src_u, src_v, dst_rgb24, yuvconstants, width); @@ -5098,6 +5247,14 @@ int I420ToARGB1555(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGB1555ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGB1555Row = I422ToARGB1555Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToARGB1555Row = I422ToARGB1555Row_LSX; + } + } +#endif #if defined(HAS_I422TOARGB1555ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGB1555Row = I422ToARGB1555Row_Any_LASX; @@ -5179,6 +5336,14 @@ int I420ToARGB4444(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGB4444ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGB4444Row = I422ToARGB4444Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToARGB4444Row = I422ToARGB4444Row_LSX; + } + } +#endif #if defined(HAS_I422TOARGB4444ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGB4444Row = I422ToARGB4444Row_Any_LASX; @@ -5261,6 +5426,14 @@ int I420ToRGB565Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB565ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGB565Row = I422ToRGB565Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGB565Row = I422ToRGB565Row_LSX; + } + } +#endif #if defined(HAS_I422TORGB565ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGB565Row = I422ToRGB565Row_Any_LASX; @@ -5393,6 +5566,14 @@ int I422ToRGB565Matrix(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TORGB565ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToRGB565Row = I422ToRGB565Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToRGB565Row = I422ToRGB565Row_LSX; + } + } +#endif #if defined(HAS_I422TORGB565ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToRGB565Row = I422ToRGB565Row_Any_LASX; @@ -5508,6 +5689,14 @@ int I420ToRGB565Dither(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGBRow = I422ToARGBRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToARGBRow = I422ToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422TOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGBRow = I422ToARGBRow_Any_LASX; @@ -5516,6 +5705,11 @@ int I420ToRGB565Dither(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToARGBRow = I422ToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBTORGB565DITHERROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { ARGBToRGB565DitherRow = ARGBToRGB565DitherRow_Any_SSE2; @@ -5774,6 +5968,11 @@ static int I420ToARGBMatrixBilinear(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToARGBRow = I444ToARGBRow_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_BILINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { @@ -5908,6 +6107,11 @@ static int I422ToARGBMatrixLinear(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToARGBRow = I444ToARGBRow_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_LINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { ScaleRowUp2_Linear = ScaleRowUp2_Linear_Any_SSE2; @@ -6020,6 +6224,11 @@ static int I420ToRGB24MatrixBilinear(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TORGB24ROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToRGB24Row = I444ToRGB24Row_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_BILINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { @@ -6539,6 +6748,11 @@ static int I420AlphaToARGBMatrixBilinear( } } #endif +#if defined(HAS_I444ALPHATOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444AlphaToARGBRow = I444AlphaToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -6571,6 +6785,11 @@ static int I420AlphaToARGBMatrixBilinear( } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_BILINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { @@ -6731,6 +6950,11 @@ static int I422AlphaToARGBMatrixLinear(const uint8_t* src_y, } } #endif +#if defined(HAS_I444ALPHATOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444AlphaToARGBRow = I444AlphaToARGBRow_RVV; + } +#endif #if defined(HAS_ARGBATTENUATEROW_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { ARGBAttenuateRow = ARGBAttenuateRow_Any_SSSE3; @@ -6763,6 +6987,12 @@ static int I422AlphaToARGBMatrixLinear(const uint8_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif + #if defined(HAS_SCALEROWUP2_LINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { ScaleRowUp2_Linear = ScaleRowUp2_Linear_Any_SSE2; @@ -6896,6 +7126,11 @@ static int I010AlphaToARGBMatrixBilinear( } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_BILINEAR_12_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { @@ -7057,6 +7292,11 @@ static int I210AlphaToARGBMatrixLinear(const uint16_t* src_y, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_LINEAR_12_SSSE3) if (TestCpuFlag(kCpuHasSSSE3)) { @@ -7486,6 +7726,11 @@ static int I422ToRGB24MatrixLinear(const uint8_t* src_y, } } #endif +#if defined(HAS_I444TORGB24ROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I444ToRGB24Row = I444ToRGB24Row_RVV; + } +#endif #if defined(HAS_SCALEROWUP2_LINEAR_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { ScaleRowUp2_Linear = ScaleRowUp2_Linear_Any_SSE2; diff --git a/libfenrir/src/main/jni/animation/libyuv/source/convert_from.cc b/libfenrir/src/main/jni/animation/libyuv/source/convert_from.cc index 8bd07e4ce..4102d610f 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/convert_from.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/convert_from.cc @@ -446,6 +446,14 @@ int I420ToYUY2(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOYUY2ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToYUY2Row = I422ToYUY2Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToYUY2Row = I422ToYUY2Row_LSX; + } + } +#endif #if defined(HAS_I422TOYUY2ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToYUY2Row = I422ToYUY2Row_Any_LASX; @@ -533,6 +541,14 @@ int I422ToUYVY(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOUYVYROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToUYVYRow = I422ToUYVYRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToUYVYRow = I422ToUYVYRow_LSX; + } + } +#endif #if defined(HAS_I422TOUYVYROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToUYVYRow = I422ToUYVYRow_Any_LASX; @@ -608,6 +624,14 @@ int I420ToUYVY(const uint8_t* src_y, } } #endif +#if defined(HAS_I422TOUYVYROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToUYVYRow = I422ToUYVYRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToUYVYRow = I422ToUYVYRow_LSX; + } + } +#endif #if defined(HAS_I422TOUYVYROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToUYVYRow = I422ToUYVYRow_Any_LASX; diff --git a/libfenrir/src/main/jni/animation/libyuv/source/convert_from_argb.cc b/libfenrir/src/main/jni/animation/libyuv/source/convert_from_argb.cc index 47ee3437e..eae3ea0df 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/convert_from_argb.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/convert_from_argb.cc @@ -132,6 +132,11 @@ int ARGBToI444(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBToUV444Row(src_argb, dst_u, dst_v, width); @@ -256,6 +261,11 @@ int ARGBToI422(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBToUVRow(src_argb, 0, dst_u, dst_v, width); @@ -373,6 +383,11 @@ int ARGBToNV12(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -551,6 +566,11 @@ int ARGBToNV21(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -726,6 +746,11 @@ int ABGRToNV12(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYRow = ABGRToYRow_RVV; + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -902,6 +927,11 @@ int ABGRToNV21(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYRow = ABGRToYRow_RVV; + } +#endif #if defined(HAS_MERGEUVROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { MergeUVRow_ = MergeUVRow_Any_SSE2; @@ -1085,6 +1115,11 @@ int ARGBToYUY2(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif #if defined(HAS_I422TOYUY2ROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { I422ToYUY2Row = I422ToYUY2Row_Any_SSE2; @@ -1117,6 +1152,14 @@ int ARGBToYUY2(const uint8_t* src_argb, } } #endif +#if defined(HAS_I422TOYUY2ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToYUY2Row = I422ToYUY2Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToYUY2Row = I422ToYUY2Row_LSX; + } + } +#endif #if defined(HAS_I422TOYUY2ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToYUY2Row = I422ToYUY2Row_Any_LASX; @@ -1256,6 +1299,11 @@ int ARGBToUYVY(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif #if defined(HAS_I422TOUYVYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { I422ToUYVYRow = I422ToUYVYRow_Any_SSE2; @@ -1288,6 +1336,14 @@ int ARGBToUYVY(const uint8_t* src_argb, } } #endif +#if defined(HAS_I422TOUYVYROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToUYVYRow = I422ToUYVYRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + I422ToUYVYRow = I422ToUYVYRow_LSX; + } + } +#endif #if defined(HAS_I422TOUYVYROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToUYVYRow = I422ToUYVYRow_Any_LASX; @@ -1389,6 +1445,11 @@ int ARGBToI400(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYRow = ARGBToYRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBToYRow(src_argb, dst_y, width); @@ -2088,6 +2149,11 @@ int ARGBToJ420(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYJRow = ARGBToYJRow_RVV; + } +#endif for (y = 0; y < height - 1; y += 2) { ARGBToUVJRow(src_argb, src_stride_argb, dst_uj, dst_vj, width); @@ -2219,6 +2285,11 @@ int ARGBToJ422(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYJRow = ARGBToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBToUVJRow(src_argb, 0, dst_uj, dst_vj, width); @@ -2288,6 +2359,11 @@ int ARGBToJ400(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYJRow = ARGBToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBToYJRow(src_argb, dst_yj, width); @@ -2370,6 +2446,11 @@ int RGBAToJ400(const uint8_t* src_rgba, } } #endif +#if defined(HAS_RGBATOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RGBAToYJRow = RGBAToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { RGBAToYJRow(src_rgba, dst_yj, width); @@ -2480,6 +2561,11 @@ int ABGRToJ420(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYJRow = ABGRToYJRow_RVV; + } +#endif for (y = 0; y < height - 1; y += 2) { ABGRToUVJRow(src_abgr, src_stride_abgr, dst_uj, dst_vj, width); @@ -2607,6 +2693,11 @@ int ABGRToJ422(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYJRow = ABGRToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ABGRToUVJRow(src_abgr, 0, dst_uj, dst_vj, width); @@ -2692,6 +2783,11 @@ int ABGRToJ400(const uint8_t* src_abgr, } } #endif +#if defined(HAS_ABGRTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ABGRToYJRow = ABGRToYJRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ABGRToYJRow(src_abgr, dst_yj, width); @@ -2830,7 +2926,8 @@ int ARGBToAB64(const uint8_t* src_argb, } // Enabled if 1 pass is available -#if defined(HAS_RAWTOYJROW_NEON) || defined(HAS_RAWTOYJROW_MSA) +#if defined(HAS_RAWTOYJROW_NEON) || defined(HAS_RAWTOYJROW_MSA) || \ + defined(HAS_RAWTOYJROW_RVV) #define HAS_RAWTOYJROW #endif @@ -2912,6 +3009,11 @@ int RAWToJNV21(const uint8_t* src_raw, } } #endif +#if defined(HAS_RAWTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + RAWToYJRow = RAWToYJRow_RVV; + } +#endif // Other platforms do intermediate conversion from RAW to ARGB. #else // HAS_RAWTOYJROW diff --git a/libfenrir/src/main/jni/animation/libyuv/source/planar_functions.cc b/libfenrir/src/main/jni/animation/libyuv/source/planar_functions.cc index c6f9d5c75..fd12718da 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/planar_functions.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/planar_functions.cc @@ -2113,6 +2113,16 @@ int YUY2ToI422(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_LSX) && defined(HAS_YUY2TOUV422ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + YUY2ToYRow = YUY2ToYRow_Any_LSX; + YUY2ToUV422Row = YUY2ToUV422Row_Any_LSX; + if (IS_ALIGNED(width, 16)) { + YUY2ToYRow = YUY2ToYRow_LSX; + YUY2ToUV422Row = YUY2ToUV422Row_LSX; + } + } +#endif #if defined(HAS_YUY2TOYROW_LASX) && defined(HAS_YUY2TOUV422ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { YUY2ToYRow = YUY2ToYRow_Any_LASX; @@ -2414,6 +2424,14 @@ void MirrorPlane(const uint8_t* src_y, } } #endif +#if defined(HAS_MIRRORROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + MirrorRow = MirrorRow_Any_LSX; + if (IS_ALIGNED(width, 32)) { + MirrorRow = MirrorRow_LSX; + } + } +#endif #if defined(HAS_MIRRORROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { MirrorRow = MirrorRow_Any_LASX; @@ -2480,6 +2498,14 @@ void MirrorUVPlane(const uint8_t* src_uv, } } #endif +#if defined(HAS_MIRRORUVROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + MirrorUVRow = MirrorUVRow_Any_LSX; + if (IS_ALIGNED(width, 8)) { + MirrorUVRow = MirrorUVRow_LSX; + } + } +#endif #if defined(HAS_MIRRORUVROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { MirrorUVRow = MirrorUVRow_Any_LASX; @@ -2652,6 +2678,14 @@ int ARGBMirror(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBMIRRORROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBMirrorRow = ARGBMirrorRow_Any_LSX; + if (IS_ALIGNED(width, 8)) { + ARGBMirrorRow = ARGBMirrorRow_LSX; + } + } +#endif #if defined(HAS_ARGBMIRRORROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { ARGBMirrorRow = ARGBMirrorRow_Any_LASX; @@ -3532,6 +3566,11 @@ int ARGBAttenuate(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBATTENUATEROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBAttenuateRow = ARGBAttenuateRow_RVV; + } +#endif for (y = 0; y < height; ++y) { ARGBAttenuateRow(src_argb, dst_argb, width); @@ -4675,6 +4714,11 @@ static int ARGBSobelize(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBTOYJROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + ARGBToYJRow = ARGBToYJRow_RVV; + } +#endif #if defined(HAS_SOBELYROW_SSE2) if (TestCpuFlag(kCpuHasSSE2)) { @@ -5314,6 +5358,14 @@ int YUY2ToNV12(const uint8_t* src_yuy2, } } #endif +#if defined(HAS_YUY2TOYROW_LSX) && defined(HAS_YUY2TOUV422ROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + YUY2ToYRow = YUY2ToYRow_Any_LSX; + if (IS_ALIGNED(width, 16)) { + YUY2ToYRow = YUY2ToYRow_LSX; + } + } +#endif #if defined(HAS_YUY2TOYROW_LASX) && defined(HAS_YUY2TOUV422ROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { YUY2ToYRow = YUY2ToYRow_Any_LASX; diff --git a/libfenrir/src/main/jni/animation/libyuv/source/rotate.cc b/libfenrir/src/main/jni/animation/libyuv/source/rotate.cc index b1b4458e6..6797ff02b 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/rotate.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/rotate.cc @@ -178,6 +178,14 @@ void RotatePlane180(const uint8_t* src, } } #endif +#if defined(HAS_MIRRORROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + MirrorRow = MirrorRow_Any_LSX; + if (IS_ALIGNED(width, 32)) { + MirrorRow = MirrorRow_LSX; + } + } +#endif #if defined(HAS_MIRRORROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { MirrorRow = MirrorRow_Any_LASX; diff --git a/libfenrir/src/main/jni/animation/libyuv/source/rotate_argb.cc b/libfenrir/src/main/jni/animation/libyuv/source/rotate_argb.cc index 28226210e..9667f34c2 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/rotate_argb.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/rotate_argb.cc @@ -156,6 +156,14 @@ static int ARGBRotate180(const uint8_t* src_argb, } } #endif +#if defined(HAS_ARGBMIRRORROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + ARGBMirrorRow = ARGBMirrorRow_Any_LSX; + if (IS_ALIGNED(width, 8)) { + ARGBMirrorRow = ARGBMirrorRow_LSX; + } + } +#endif #if defined(HAS_ARGBMIRRORROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { ARGBMirrorRow = ARGBMirrorRow_Any_LASX; diff --git a/libfenrir/src/main/jni/animation/libyuv/source/row_any.cc b/libfenrir/src/main/jni/animation/libyuv/source/row_any.cc index 37aa1fba8..27b12a7a8 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/row_any.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/row_any.cc @@ -113,6 +113,9 @@ ANY41C(I444AlphaToARGBRow_Any_MSA, I444AlphaToARGBRow_MSA, 0, 0, 4, 7) #ifdef HAS_I422ALPHATOARGBROW_MSA ANY41C(I422AlphaToARGBRow_Any_MSA, I422AlphaToARGBRow_MSA, 1, 0, 4, 7) #endif +#ifdef HAS_I422ALPHATOARGBROW_LSX +ANY41C(I422AlphaToARGBRow_Any_LSX, I422AlphaToARGBRow_LSX, 1, 0, 4, 15) +#endif #ifdef HAS_I422ALPHATOARGBROW_LASX ANY41C(I422AlphaToARGBRow_Any_LASX, I422AlphaToARGBRow_LASX, 1, 0, 4, 15) #endif @@ -284,6 +287,9 @@ ANY31(I422ToYUY2Row_Any_NEON, I422ToYUY2Row_NEON, 1, 1, 4, 15) #ifdef HAS_I422TOYUY2ROW_MSA ANY31(I422ToYUY2Row_Any_MSA, I422ToYUY2Row_MSA, 1, 1, 4, 31) #endif +#ifdef HAS_I422TOYUY2ROW_LSX +ANY31(I422ToYUY2Row_Any_LSX, I422ToYUY2Row_LSX, 1, 1, 4, 15) +#endif #ifdef HAS_I422TOYUY2ROW_LASX ANY31(I422ToYUY2Row_Any_LASX, I422ToYUY2Row_LASX, 1, 1, 4, 31) #endif @@ -293,6 +299,9 @@ ANY31(I422ToUYVYRow_Any_NEON, I422ToUYVYRow_NEON, 1, 1, 4, 15) #ifdef HAS_I422TOUYVYROW_MSA ANY31(I422ToUYVYRow_Any_MSA, I422ToUYVYRow_MSA, 1, 1, 4, 31) #endif +#ifdef HAS_I422TOUYVYROW_LSX +ANY31(I422ToUYVYRow_Any_LSX, I422ToUYVYRow_LSX, 1, 1, 4, 15) +#endif #ifdef HAS_I422TOUYVYROW_LASX ANY31(I422ToUYVYRow_Any_LASX, I422ToUYVYRow_LASX, 1, 1, 4, 31) #endif @@ -408,6 +417,14 @@ ANY31C(I422ToARGB4444Row_Any_MSA, I422ToARGB4444Row_MSA, 1, 0, 2, 7) ANY31C(I422ToARGB1555Row_Any_MSA, I422ToARGB1555Row_MSA, 1, 0, 2, 7) ANY31C(I422ToRGB565Row_Any_MSA, I422ToRGB565Row_MSA, 1, 0, 2, 7) #endif +#ifdef HAS_I422TOARGBROW_LSX +ANY31C(I422ToARGBRow_Any_LSX, I422ToARGBRow_LSX, 1, 0, 4, 15) +ANY31C(I422ToRGBARow_Any_LSX, I422ToRGBARow_LSX, 1, 0, 4, 15) +ANY31C(I422ToRGB24Row_Any_LSX, I422ToRGB24Row_LSX, 1, 0, 3, 15) +ANY31C(I422ToRGB565Row_Any_LSX, I422ToRGB565Row_LSX, 1, 0, 2, 15) +ANY31C(I422ToARGB4444Row_Any_LSX, I422ToARGB4444Row_LSX, 1, 0, 2, 15) +ANY31C(I422ToARGB1555Row_Any_LSX, I422ToARGB1555Row_LSX, 1, 0, 2, 15) +#endif #ifdef HAS_I422TOARGBROW_LASX ANY31C(I422ToARGBRow_Any_LASX, I422ToARGBRow_LASX, 1, 0, 4, 31) ANY31C(I422ToRGBARow_Any_LASX, I422ToRGBARow_LASX, 1, 0, 4, 31) @@ -1204,6 +1221,9 @@ ANY11(UYVYToYRow_Any_NEON, UYVYToYRow_NEON, 1, 4, 1, 15) #ifdef HAS_YUY2TOYROW_MSA ANY11(YUY2ToYRow_Any_MSA, YUY2ToYRow_MSA, 1, 4, 1, 31) #endif +#ifdef HAS_YUY2TOYROW_LSX +ANY11(YUY2ToYRow_Any_LSX, YUY2ToYRow_LSX, 1, 4, 1, 15) +#endif #ifdef HAS_YUY2TOYROW_LASX ANY11(YUY2ToYRow_Any_LASX, YUY2ToYRow_LASX, 1, 4, 1, 31) #endif @@ -1842,6 +1862,9 @@ ANY11M(MirrorRow_Any_NEON, MirrorRow_NEON, 1, 31) #ifdef HAS_MIRRORROW_MSA ANY11M(MirrorRow_Any_MSA, MirrorRow_MSA, 1, 63) #endif +#ifdef HAS_MIRRORROW_LSX +ANY11M(MirrorRow_Any_LSX, MirrorRow_LSX, 1, 31) +#endif #ifdef HAS_MIRRORROW_LASX ANY11M(MirrorRow_Any_LASX, MirrorRow_LASX, 1, 63) #endif @@ -1857,6 +1880,9 @@ ANY11M(MirrorUVRow_Any_NEON, MirrorUVRow_NEON, 2, 31) #ifdef HAS_MIRRORUVROW_MSA ANY11M(MirrorUVRow_Any_MSA, MirrorUVRow_MSA, 2, 7) #endif +#ifdef HAS_MIRRORUVROW_LSX +ANY11M(MirrorUVRow_Any_LSX, MirrorUVRow_LSX, 2, 7) +#endif #ifdef HAS_MIRRORUVROW_LASX ANY11M(MirrorUVRow_Any_LASX, MirrorUVRow_LASX, 2, 15) #endif @@ -1872,6 +1898,9 @@ ANY11M(ARGBMirrorRow_Any_NEON, ARGBMirrorRow_NEON, 4, 7) #ifdef HAS_ARGBMIRRORROW_MSA ANY11M(ARGBMirrorRow_Any_MSA, ARGBMirrorRow_MSA, 4, 15) #endif +#ifdef HAS_ARGBMIRRORROW_LSX +ANY11M(ARGBMirrorRow_Any_LSX, ARGBMirrorRow_LSX, 4, 7) +#endif #ifdef HAS_ARGBMIRRORROW_LASX ANY11M(ARGBMirrorRow_Any_LASX, ARGBMirrorRow_LASX, 4, 15) #endif @@ -1970,6 +1999,9 @@ ANY12(ARGBToUV444Row_Any_MSA, ARGBToUV444Row_MSA, 0, 4, 0, 15) ANY12(YUY2ToUV422Row_Any_MSA, YUY2ToUV422Row_MSA, 1, 4, 1, 31) ANY12(UYVYToUV422Row_Any_MSA, UYVYToUV422Row_MSA, 1, 4, 1, 31) #endif +#ifdef HAS_YUY2TOUV422ROW_LSX +ANY12(YUY2ToUV422Row_Any_LSX, YUY2ToUV422Row_LSX, 1, 4, 1, 15) +#endif #ifdef HAS_YUY2TOUV422ROW_LASX ANY12(ARGBToUV444Row_Any_LASX, ARGBToUV444Row_LASX, 0, 4, 0, 31) ANY12(YUY2ToUV422Row_Any_LASX, YUY2ToUV422Row_LASX, 1, 4, 1, 31) @@ -2251,6 +2283,9 @@ ANY12S(UYVYToUVRow_Any_NEON, UYVYToUVRow_NEON, 1, 4, 15) #ifdef HAS_YUY2TOUVROW_MSA ANY12S(YUY2ToUVRow_Any_MSA, YUY2ToUVRow_MSA, 1, 4, 31) #endif +#ifdef HAS_YUY2TOUVROW_LSX +ANY12S(YUY2ToUVRow_Any_LSX, YUY2ToUVRow_LSX, 1, 4, 15) +#endif #ifdef HAS_YUY2TOUVROW_LASX ANY12S(YUY2ToUVRow_Any_LASX, YUY2ToUVRow_LASX, 1, 4, 31) #endif diff --git a/libfenrir/src/main/jni/animation/libyuv/source/row_common.cc b/libfenrir/src/main/jni/animation/libyuv/source/row_common.cc index 74c9be87e..b7655b7b1 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/row_common.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/row_common.cc @@ -1484,7 +1484,7 @@ void J400ToARGBRow_C(const uint8_t* src_y, uint8_t* dst_argb, int width) { // clang-format off -#if defined(__aarch64__) || defined(__arm__) +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv) // Bias values include subtract 128 from U and V, bias from Y and rounding. // For B and R bias is negative. For G bias is positive. #define YUVCONSTANTSBODY(YG, YB, UB, UG, VG, VR) \ @@ -1680,7 +1680,7 @@ MAKEYUVCONSTANTS(V2020, YG, YB, UB, UG, VG, VR) #undef MAKEYUVCONSTANTS -#if defined(__aarch64__) || defined(__arm__) +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv) #define LOAD_YUV_CONSTANTS \ int ub = yuvconstants->kUVCoeff[0]; \ int vr = yuvconstants->kUVCoeff[1]; \ @@ -1868,7 +1868,7 @@ static __inline void YPixel(uint8_t y, uint8_t* g, uint8_t* r, const struct YuvConstants* yuvconstants) { -#if defined(__aarch64__) || defined(__arm__) +#if defined(__aarch64__) || defined(__arm__) || defined(__riscv) int yg = yuvconstants->kRGBCoeffBias[0]; int ygb = yuvconstants->kRGBCoeffBias[4]; #else diff --git a/libfenrir/src/main/jni/animation/libyuv/source/row_lsx.cc b/libfenrir/src/main/jni/animation/libyuv/source/row_lsx.cc index 9c1e16f22..15595efef 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/row_lsx.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/row_lsx.cc @@ -31,6 +31,91 @@ extern "C" { yb = __lsx_vreplgr2vr_w(yuvconst->kYBiasToRgb[0]); \ } +// Load 32 YUV422 pixel data +#define READYUV422_D(psrc_y, psrc_u, psrc_v, out_y, uv_l, uv_h) \ + { \ + __m128i temp0, temp1; \ + \ + DUP2_ARG2(__lsx_vld, psrc_y, 0, psrc_u, 0, out_y, temp0); \ + temp1 = __lsx_vld(psrc_v, 0); \ + temp0 = __lsx_vsub_b(temp0, const_80); \ + temp1 = __lsx_vsub_b(temp1, const_80); \ + temp0 = __lsx_vsllwil_h_b(temp0, 0); \ + temp1 = __lsx_vsllwil_h_b(temp1, 0); \ + uv_l = __lsx_vilvl_h(temp0, temp1); \ + uv_h = __lsx_vilvh_h(temp0, temp1); \ + } + +// Load 16 YUV422 pixel data +#define READYUV422(psrc_y, psrc_u, psrc_v, out_y, uv) \ + { \ + __m128i temp0, temp1; \ + \ + out_y = __lsx_vld(psrc_y, 0); \ + temp0 = __lsx_vldrepl_d(psrc_u, 0); \ + temp1 = __lsx_vldrepl_d(psrc_v, 0); \ + uv = __lsx_vilvl_b(temp0, temp1); \ + uv = __lsx_vsub_b(uv, const_80); \ + uv = __lsx_vsllwil_h_b(uv, 0); \ + } + +// Convert 16 pixels of YUV420 to RGB. +#define YUVTORGB_D(in_y, in_uvl, in_uvh, ubvr, ugvg, yg, yb, b_l, b_h, g_l, \ + g_h, r_l, r_h) \ + { \ + __m128i u_l, u_h, v_l, v_h; \ + __m128i yl_ev, yl_od, yh_ev, yh_od; \ + __m128i temp0, temp1, temp2, temp3; \ + \ + temp0 = __lsx_vilvl_b(in_y, in_y); \ + temp1 = __lsx_vilvh_b(in_y, in_y); \ + yl_ev = __lsx_vmulwev_w_hu_h(temp0, yg); \ + yl_od = __lsx_vmulwod_w_hu_h(temp0, yg); \ + yh_ev = __lsx_vmulwev_w_hu_h(temp1, yg); \ + yh_od = __lsx_vmulwod_w_hu_h(temp1, yg); \ + DUP4_ARG2(__lsx_vsrai_w, yl_ev, 16, yl_od, 16, yh_ev, 16, yh_od, 16, \ + yl_ev, yl_od, yh_ev, yh_od); \ + yl_ev = __lsx_vadd_w(yl_ev, yb); \ + yl_od = __lsx_vadd_w(yl_od, yb); \ + yh_ev = __lsx_vadd_w(yh_ev, yb); \ + yh_od = __lsx_vadd_w(yh_od, yb); \ + v_l = __lsx_vmulwev_w_h(in_uvl, ubvr); \ + u_l = __lsx_vmulwod_w_h(in_uvl, ubvr); \ + v_h = __lsx_vmulwev_w_h(in_uvh, ubvr); \ + u_h = __lsx_vmulwod_w_h(in_uvh, ubvr); \ + temp0 = __lsx_vadd_w(yl_ev, u_l); \ + temp1 = __lsx_vadd_w(yl_od, u_l); \ + temp2 = __lsx_vadd_w(yh_ev, u_h); \ + temp3 = __lsx_vadd_w(yh_od, u_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + b_l = __lsx_vpackev_h(temp1, temp0); \ + b_h = __lsx_vpackev_h(temp3, temp2); \ + temp0 = __lsx_vadd_w(yl_ev, v_l); \ + temp1 = __lsx_vadd_w(yl_od, v_l); \ + temp2 = __lsx_vadd_w(yh_ev, v_h); \ + temp3 = __lsx_vadd_w(yh_od, v_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + r_l = __lsx_vpackev_h(temp1, temp0); \ + r_h = __lsx_vpackev_h(temp3, temp2); \ + DUP2_ARG2(__lsx_vdp2_w_h, in_uvl, ugvg, in_uvh, ugvg, u_l, u_h); \ + temp0 = __lsx_vsub_w(yl_ev, u_l); \ + temp1 = __lsx_vsub_w(yl_od, u_l); \ + temp2 = __lsx_vsub_w(yh_ev, u_h); \ + temp3 = __lsx_vsub_w(yh_od, u_h); \ + DUP4_ARG2(__lsx_vsrai_w, temp0, 6, temp1, 6, temp2, 6, temp3, 6, temp0, \ + temp1, temp2, temp3); \ + DUP4_ARG1(__lsx_vclip255_w, temp0, temp1, temp2, temp3, temp0, temp1, \ + temp2, temp3); \ + g_l = __lsx_vpackev_h(temp1, temp0); \ + g_h = __lsx_vpackev_h(temp3, temp2); \ + } + // Convert 8 pixels of YUV420 to RGB. #define YUVTORGB(in_y, in_vu, vrub, vgug, yg, yb, out_b, out_g, out_r) \ { \ @@ -118,6 +203,25 @@ extern "C" { out_g = __lsx_vpackev_h(tmp1, tmp0); \ } +// Pack and Store 16 ARGB values. +#define STOREARGB_D(a_l, a_h, r_l, r_h, g_l, g_h, b_l, b_h, pdst_argb) \ + { \ + __m128i temp0, temp1, temp2, temp3; \ + temp0 = __lsx_vpackev_b(g_l, b_l); \ + temp1 = __lsx_vpackev_b(a_l, r_l); \ + temp2 = __lsx_vpackev_b(g_h, b_h); \ + temp3 = __lsx_vpackev_b(a_h, r_h); \ + r_l = __lsx_vilvl_h(temp1, temp0); \ + r_h = __lsx_vilvh_h(temp1, temp0); \ + g_l = __lsx_vilvl_h(temp3, temp2); \ + g_h = __lsx_vilvh_h(temp3, temp2); \ + __lsx_vst(r_l, pdst_argb, 0); \ + __lsx_vst(r_h, pdst_argb, 16); \ + __lsx_vst(g_l, pdst_argb, 32); \ + __lsx_vst(g_h, pdst_argb, 48); \ + pdst_argb += 64; \ + } + // Pack and Store 8 ARGB values. #define STOREARGB(in_a, in_r, in_g, in_b, pdst_argb) \ { \ @@ -155,6 +259,460 @@ extern "C" { _dst0 = __lsx_vpickod_b(_reg1, _reg0); \ } +void MirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width) { + int x; + int len = width / 32; + __m128i src0, src1; + __m128i shuffler = {0x08090A0B0C0D0E0F, 0x0001020304050607}; + src += width - 32; + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); + DUP2_ARG3(__lsx_vshuf_b, src0, src0, shuffler, src1, src1, shuffler, src0, + src1); + __lsx_vst(src1, dst, 0); + __lsx_vst(src0, dst, 16); + dst += 32; + src -= 32; + } +} + +void MirrorUVRow_LSX(const uint8_t* src_uv, uint8_t* dst_uv, int width) { + int x; + int len = width / 8; + __m128i src, dst; + __m128i shuffler = {0x0004000500060007, 0x0000000100020003}; + + src_uv += (width - 8) << 1; + for (x = 0; x < len; x++) { + src = __lsx_vld(src_uv, 0); + dst = __lsx_vshuf_h(shuffler, src, src); + __lsx_vst(dst, dst_uv, 0); + src_uv -= 16; + dst_uv += 16; + } +} + +void ARGBMirrorRow_LSX(const uint8_t* src, uint8_t* dst, int width) { + int x; + int len = width / 8; + __m128i src0, src1; + __m128i shuffler = {0x0B0A09080F0E0D0C, 0x0302010007060504}; + + src += (width * 4) - 32; + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src, 0, src, 16, src0, src1); + DUP2_ARG3(__lsx_vshuf_b, src0, src0, shuffler, src1, src1, shuffler, src0, + src1); + __lsx_vst(src1, dst, 0); + __lsx_vst(src0, dst, 16); + dst += 32; + src -= 32; + } +} + +void I422ToYUY2Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_yuy2, + int width) { + int x; + int len = width / 16; + __m128i src_u0, src_v0, src_y0, vec_uv0; + __m128i vec_yuy2_0, vec_yuy2_1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_u, 0, src_v, 0, src_u0, src_v0); + src_y0 = __lsx_vld(src_y, 0); + vec_uv0 = __lsx_vilvl_b(src_v0, src_u0); + vec_yuy2_0 = __lsx_vilvl_b(vec_uv0, src_y0); + vec_yuy2_1 = __lsx_vilvh_b(vec_uv0, src_y0); + __lsx_vst(vec_yuy2_0, dst_yuy2, 0); + __lsx_vst(vec_yuy2_1, dst_yuy2, 16); + src_u += 8; + src_v += 8; + src_y += 16; + dst_yuy2 += 32; + } +} + +void I422ToUYVYRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_uyvy, + int width) { + int x; + int len = width / 16; + __m128i src_u0, src_v0, src_y0, vec_uv0; + __m128i vec_uyvy0, vec_uyvy1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_u, 0, src_v, 0, src_u0, src_v0); + src_y0 = __lsx_vld(src_y, 0); + vec_uv0 = __lsx_vilvl_b(src_v0, src_u0); + vec_uyvy0 = __lsx_vilvl_b(src_y0, vec_uv0); + vec_uyvy1 = __lsx_vilvh_b(src_y0, vec_uv0); + __lsx_vst(vec_uyvy0, dst_uyvy, 0); + __lsx_vst(vec_uyvy1, dst_uyvy, 16); + src_u += 8; + src_v += 8; + src_y += 16; + dst_uyvy += 32; + } +} + +void I422ToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_ug, vec_vr, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i alpha = __lsx_vldi(0xFF); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(alpha, alpha, r_l, r_h, g_l, g_h, b_l, b_h, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422ToRGBARow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i alpha = __lsx_vldi(0xFF); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(r_l, r_h, g_l, g_h, b_l, b_h, alpha, alpha, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422AlphaToARGBRow_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + int res = width & 15; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i zero = __lsx_vldi(0); + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h, a_l, a_h; + + y = __lsx_vld(src_a, 0); + a_l = __lsx_vilvl_b(zero, y); + a_h = __lsx_vilvh_b(zero, y); + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + STOREARGB_D(a_l, a_h, r_l, r_h, g_l, g_h, b_l, b_h, dst_argb); + src_y += 16; + src_u += 8; + src_v += 8; + src_a += 16; + } + if (res) { + __m128i y, uv, r, g, b, a; + a = __lsx_vld(src_a, 0); + a = __lsx_vsllwil_hu_bu(a, 0); + READYUV422(src_y, src_u, src_v, y, uv); + YUVTORGB(y, uv, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b, g, r); + STOREARGB(a, r, g, b, dst_argb); + } +} + +void I422ToRGB24Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int32_t width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i shuffler0 = {0x0504120302100100, 0x0A18090816070614}; + __m128i shuffler1 = {0x1E0F0E1C0D0C1A0B, 0x1E0F0E1C0D0C1A0B}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + __m128i temp0, temp1, temp2, temp3; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + temp0 = __lsx_vpackev_b(g_l, b_l); + temp1 = __lsx_vpackev_b(g_h, b_h); + DUP4_ARG3(__lsx_vshuf_b, r_l, temp0, shuffler1, r_h, temp1, shuffler1, r_l, + temp0, shuffler0, r_h, temp1, shuffler0, temp2, temp3, temp0, + temp1); + + b_l = __lsx_vilvl_d(temp1, temp2); + b_h = __lsx_vilvh_d(temp3, temp1); + __lsx_vst(temp0, dst_argb, 0); + __lsx_vst(b_l, dst_argb, 16); + __lsx_vst(b_h, dst_argb, 32); + dst_argb += 48; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +// TODO(fbarchard): Consider AND instead of shift to isolate 5 upper bits of R. +void I422ToRGB565Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb565, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 3); + b_h = __lsx_vsrli_h(b_h, 3); + g_l = __lsx_vsrli_h(g_l, 2); + g_h = __lsx_vsrli_h(g_h, 2); + r_l = __lsx_vsrli_h(r_l, 3); + r_h = __lsx_vsrli_h(r_h, 3); + r_l = __lsx_vslli_h(r_l, 11); + r_h = __lsx_vslli_h(r_h, 11); + g_l = __lsx_vslli_h(g_l, 5); + g_h = __lsx_vslli_h(g_h, 5); + r_l = __lsx_vor_v(r_l, g_l); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, g_h); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_rgb565, 0); + __lsx_vst(r_h, dst_rgb565, 16); + dst_rgb565 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +// TODO(fbarchard): Consider AND instead of shift to isolate 4 upper bits of G. +void I422ToARGB4444Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb4444, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i alpha = {0xF000F000F000F000, 0xF000F000F000F000}; + __m128i mask = {0x00F000F000F000F0, 0x00F000F000F000F0}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 4); + b_h = __lsx_vsrli_h(b_h, 4); + r_l = __lsx_vsrli_h(r_l, 4); + r_h = __lsx_vsrli_h(r_h, 4); + g_l = __lsx_vand_v(g_l, mask); + g_h = __lsx_vand_v(g_h, mask); + r_l = __lsx_vslli_h(r_l, 8); + r_h = __lsx_vslli_h(r_h, 8); + r_l = __lsx_vor_v(r_l, alpha); + r_h = __lsx_vor_v(r_h, alpha); + r_l = __lsx_vor_v(r_l, g_l); + r_h = __lsx_vor_v(r_h, g_h); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_argb4444, 0); + __lsx_vst(r_h, dst_argb4444, 16); + dst_argb4444 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void I422ToARGB1555Row_LSX(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb1555, + const struct YuvConstants* yuvconstants, + int width) { + int x; + int len = width / 16; + __m128i vec_yb, vec_yg, vec_ub, vec_vr, vec_ug, vec_vg; + __m128i vec_ubvr, vec_ugvg; + __m128i const_80 = __lsx_vldi(0x80); + __m128i alpha = {0x8000800080008000, 0x8000800080008000}; + + YUVTORGB_SETUP(yuvconstants, vec_vr, vec_ub, vec_vg, vec_ug, vec_yg, vec_yb); + vec_ubvr = __lsx_vilvl_h(vec_ub, vec_vr); + vec_ugvg = __lsx_vilvl_h(vec_ug, vec_vg); + + for (x = 0; x < len; x++) { + __m128i y, uv_l, uv_h, b_l, b_h, g_l, g_h, r_l, r_h; + + READYUV422_D(src_y, src_u, src_v, y, uv_l, uv_h); + YUVTORGB_D(y, uv_l, uv_h, vec_ubvr, vec_ugvg, vec_yg, vec_yb, b_l, b_h, g_l, + g_h, r_l, r_h); + b_l = __lsx_vsrli_h(b_l, 3); + b_h = __lsx_vsrli_h(b_h, 3); + g_l = __lsx_vsrli_h(g_l, 3); + + g_h = __lsx_vsrli_h(g_h, 3); + g_l = __lsx_vslli_h(g_l, 5); + g_h = __lsx_vslli_h(g_h, 5); + r_l = __lsx_vsrli_h(r_l, 3); + r_h = __lsx_vsrli_h(r_h, 3); + r_l = __lsx_vslli_h(r_l, 10); + r_h = __lsx_vslli_h(r_h, 10); + r_l = __lsx_vor_v(r_l, alpha); + r_h = __lsx_vor_v(r_h, alpha); + r_l = __lsx_vor_v(r_l, g_l); + r_h = __lsx_vor_v(r_h, g_h); + r_l = __lsx_vor_v(r_l, b_l); + r_h = __lsx_vor_v(r_h, b_h); + __lsx_vst(r_l, dst_argb1555, 0); + __lsx_vst(r_h, dst_argb1555, 16); + dst_argb1555 += 32; + src_y += 16; + src_u += 8; + src_v += 8; + } +} + +void YUY2ToYRow_LSX(const uint8_t* src_yuy2, uint8_t* dst_y, int width) { + int x; + int len = width / 16; + __m128i src0, src1, dst0; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src0, src1); + dst0 = __lsx_vpickev_b(src1, src0); + __lsx_vst(dst0, dst_y, 0); + src_yuy2 += 32; + dst_y += 16; + } +} + +void YUY2ToUVRow_LSX(const uint8_t* src_yuy2, + int src_stride_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + const uint8_t* src_yuy2_next = src_yuy2 + src_stride_yuy2; + int x; + int len = width / 16; + __m128i src0, src1, src2, src3; + __m128i tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP4_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src_yuy2_next, 0, + src_yuy2_next, 16, src0, src1, src2, src3); + src0 = __lsx_vpickod_b(src1, src0); + src1 = __lsx_vpickod_b(src3, src2); + tmp0 = __lsx_vavgr_bu(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_yuy2 += 32; + src_yuy2_next += 32; + dst_u += 8; + dst_v += 8; + } +} + +void YUY2ToUV422Row_LSX(const uint8_t* src_yuy2, + uint8_t* dst_u, + uint8_t* dst_v, + int width) { + int x; + int len = width / 16; + __m128i src0, src1, tmp0, dst0, dst1; + + for (x = 0; x < len; x++) { + DUP2_ARG2(__lsx_vld, src_yuy2, 0, src_yuy2, 16, src0, src1); + tmp0 = __lsx_vpickod_b(src1, src0); + dst0 = __lsx_vpickev_b(tmp0, tmp0); + dst1 = __lsx_vpickod_b(tmp0, tmp0); + __lsx_vstelm_d(dst0, dst_u, 0, 0); + __lsx_vstelm_d(dst1, dst_v, 0, 0); + src_yuy2 += 32; + dst_u += 8; + dst_v += 8; + } +} + void ARGB4444ToARGBRow_LSX(const uint8_t* src_argb4444, uint8_t* dst_argb, int width) { diff --git a/libfenrir/src/main/jni/animation/libyuv/source/row_rvv.cc b/libfenrir/src/main/jni/animation/libyuv/source/row_rvv.cc index 956ed9f95..904cbf7d3 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/row_rvv.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/row_rvv.cc @@ -15,11 +15,10 @@ * Contributed by Bruce Lai */ -#include - #include "libyuv/row.h" #if !defined(LIBYUV_DISABLE_RVV) && defined(__riscv_vector) +#include #include #ifdef __cplusplus @@ -27,6 +26,83 @@ namespace libyuv { extern "C" { #endif +// Fill YUV -> RGB conversion constants into vectors +// NOTE: To match behavior on other platforms, vxrm (fixed-point rounding mode +// register) is set to round-down mode(2). +#define YUVTORGB_SETUP(yuvconst, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, \ + v_br) \ + { \ + asm volatile("csrwi vxrm, 2"); \ + vl = __riscv_vsetvl_e8m1(w); \ + v_ub = __riscv_vmv_v_x_u8m1(yuvconst->kUVCoeff[0], vl); \ + v_vr = __riscv_vmv_v_x_u8m1(yuvconst->kUVCoeff[1], vl); \ + v_ug = __riscv_vmv_v_x_u8m1(yuvconst->kUVCoeff[2], vl); \ + v_vg = __riscv_vmv_v_x_u8m1(yuvconst->kUVCoeff[3], vl); \ + v_yg = __riscv_vmv_v_x_u16m2(yuvconst->kRGBCoeffBias[0], vl); \ + v_bb = __riscv_vmv_v_x_u16m2(yuvconst->kRGBCoeffBias[1], vl); \ + v_bg = __riscv_vmv_v_x_u16m2(yuvconst->kRGBCoeffBias[2], vl); \ + v_br = __riscv_vmv_v_x_u16m2(yuvconst->kRGBCoeffBias[3], vl); \ + } + +// Read [VLEN/8] Y, [VLEN/(8 * 2)] U and [VLEN/(8 * 2)] V from 422 +#define READYUV422(vl, v_u, v_v, v_y_16) \ + { \ + vuint8mf2_t v_tmp0, v_tmp1; \ + vuint8m1_t v_y; \ + vuint16m1_t v_u_16, v_v_16; \ + vl = __riscv_vsetvl_e8mf2((w + 1) / 2); \ + v_tmp0 = __riscv_vle8_v_u8mf2(src_u, vl); \ + v_u_16 = __riscv_vwaddu_vx_u16m1(v_tmp0, 0, vl); \ + v_tmp1 = __riscv_vle8_v_u8mf2(src_v, vl); \ + v_v_16 = __riscv_vwaddu_vx_u16m1(v_tmp1, 0, vl); \ + v_v_16 = __riscv_vmul_vx_u16m1(v_v_16, 0x0101, vl); \ + v_u_16 = __riscv_vmul_vx_u16m1(v_u_16, 0x0101, vl); \ + v_v = __riscv_vreinterpret_v_u16m1_u8m1(v_v_16); \ + v_u = __riscv_vreinterpret_v_u16m1_u8m1(v_u_16); \ + vl = __riscv_vsetvl_e8m1(w); \ + v_y = __riscv_vle8_v_u8m1(src_y, vl); \ + v_y_16 = __riscv_vwaddu_vx_u16m2(v_y, 0, vl); \ + } + +// Read [VLEN/8] Y, [VLEN/8] U, and [VLEN/8] V from 444 +#define READYUV444(vl, v_u, v_v, v_y_16) \ + { \ + vuint8m1_t v_y; \ + vl = __riscv_vsetvl_e8m1(w); \ + v_y = __riscv_vle8_v_u8m1(src_y, vl); \ + v_u = __riscv_vle8_v_u8m1(src_u, vl); \ + v_v = __riscv_vle8_v_u8m1(src_v, vl); \ + v_y_16 = __riscv_vwaddu_vx_u16m2(v_y, 0, vl); \ + } + +// Convert from YUV to fixed point RGB +#define YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, \ + v_y_16, v_g_16, v_b_16, v_r_16) \ + { \ + vuint16m2_t v_tmp0, v_tmp1, v_tmp2, v_tmp3, v_tmp4; \ + vuint32m4_t v_tmp5; \ + v_tmp0 = __riscv_vwmulu_vv_u16m2(v_u, v_ug, vl); \ + v_y_16 = __riscv_vmul_vx_u16m2(v_y_16, 0x0101, vl); \ + v_tmp0 = __riscv_vwmaccu_vv_u16m2(v_tmp0, v_vg, v_v, vl); \ + v_tmp1 = __riscv_vwmulu_vv_u16m2(v_u, v_ub, vl); \ + v_tmp5 = __riscv_vwmulu_vv_u32m4(v_y_16, v_yg, vl); \ + v_tmp2 = __riscv_vnsrl_wx_u16m2(v_tmp5, 16, vl); \ + v_tmp3 = __riscv_vadd_vv_u16m2(v_tmp2, v_bg, vl); \ + v_tmp4 = __riscv_vadd_vv_u16m2(v_tmp2, v_tmp1, vl); \ + v_tmp2 = __riscv_vwmaccu_vv_u16m2(v_tmp2, v_vr, v_v, vl); \ + v_g_16 = __riscv_vssubu_vv_u16m2(v_tmp3, v_tmp0, vl); \ + v_b_16 = __riscv_vssubu_vv_u16m2(v_tmp4, v_bb, vl); \ + v_r_16 = __riscv_vssubu_vv_u16m2(v_tmp2, v_br, vl); \ + } + +// Convert from fixed point RGB To 8 bit RGB +#define RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r) \ + { \ + v_g = __riscv_vnclipu_wx_u8m1(v_g_16, 6, vl); \ + v_b = __riscv_vnclipu_wx_u8m1(v_b_16, 6, vl); \ + v_r = __riscv_vnclipu_wx_u8m1(v_r_16, 6, vl); \ + } + void ARGBToAR64Row_RVV(const uint8_t* src_argb, uint16_t* dst_ar64, int width) { size_t avl = (size_t)4 * width; do { @@ -186,6 +262,218 @@ void RGB24ToARGBRow_RVV(const uint8_t* src_rgb24, } while (w > 0); } +void I444ToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r, v_a; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + v_a = __riscv_vmv_v_x_u8m1(255u, vl); + do { + READYUV444(vl, v_u, v_v, v_y_16); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg4e8_v_u8m1(dst_argb, v_b, v_g, v_r, v_a, vl); + w -= vl; + src_y += vl; + src_u += vl; + src_v += vl; + dst_argb += vl * 4; + } while (w > 0); +} + +void I444AlphaToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r, v_a; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + do { + READYUV444(vl, v_u, v_v, v_y_16); + v_a = __riscv_vle8_v_u8m1(src_a, vl); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg4e8_v_u8m1(dst_argb, v_b, v_g, v_r, v_a, vl); + w -= vl; + src_y += vl; + src_a += vl; + src_u += vl; + src_v += vl; + dst_argb += vl * 4; + } while (w > 0); +} + +void I444ToRGB24Row_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + do { + READYUV444(vl, v_u, v_v, v_y_16); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg3e8_v_u8m1(dst_rgb24, v_b, v_g, v_r, vl); + w -= vl; + src_y += vl; + src_u += vl; + src_v += vl; + dst_rgb24 += vl * 3; + } while (w > 0); +} + +void I422ToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r, v_a; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + v_a = __riscv_vmv_v_x_u8m1(255u, vl); + do { + READYUV422(vl, v_u, v_v, v_y_16); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg4e8_v_u8m1(dst_argb, v_b, v_g, v_r, v_a, vl); + w -= vl; + src_y += vl; + src_u += vl / 2; + src_v += vl / 2; + dst_argb += vl * 4; + } while (w > 0); +} + +void I422AlphaToARGBRow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + const uint8_t* src_a, + uint8_t* dst_argb, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r, v_a; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + do { + READYUV422(vl, v_u, v_v, v_y_16); + v_a = __riscv_vle8_v_u8m1(src_a, vl); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg4e8_v_u8m1(dst_argb, v_b, v_g, v_r, v_a, vl); + w -= vl; + src_y += vl; + src_a += vl; + src_u += vl / 2; + src_v += vl / 2; + dst_argb += vl * 4; + } while (w > 0); +} + +void I422ToRGBARow_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgba, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r, v_a; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + v_a = __riscv_vmv_v_x_u8m1(255u, vl); + do { + READYUV422(vl, v_u, v_v, v_y_16); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg4e8_v_u8m1(dst_rgba, v_a, v_b, v_g, v_r, vl); + w -= vl; + src_y += vl; + src_u += vl / 2; + src_v += vl / 2; + dst_rgba += vl * 4; + } while (w > 0); +} + +void I422ToRGB24Row_RVV(const uint8_t* src_y, + const uint8_t* src_u, + const uint8_t* src_v, + uint8_t* dst_rgb24, + const struct YuvConstants* yuvconstants, + int width) { + size_t vl; + size_t w = (size_t)width; + vuint8m1_t v_u, v_v; + vuint8m1_t v_ub, v_vr, v_ug, v_vg; + vuint8m1_t v_b, v_g, v_r; + vuint16m2_t v_yg, v_bb, v_bg, v_br; + vuint16m2_t v_y_16, v_g_16, v_b_16, v_r_16; + YUVTORGB_SETUP(yuvconstants, vl, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, + v_br); + do { + READYUV422(vl, v_u, v_v, v_y_16); + YUVTORGB(vl, v_u, v_v, v_ub, v_vr, v_ug, v_vg, v_yg, v_bb, v_bg, v_br, + v_y_16, v_g_16, v_b_16, v_r_16); + RGBTORGB8(vl, v_g_16, v_b_16, v_r_16, v_g, v_b, v_r); + __riscv_vsseg3e8_v_u8m1(dst_rgb24, v_b, v_g, v_r, vl); + w -= vl; + src_y += vl; + src_u += vl / 2; + src_v += vl / 2; + dst_rgb24 += vl * 3; + } while (w > 0); +} + void SplitRGBRow_RVV(const uint8_t* src_rgb, uint8_t* dst_r, uint8_t* dst_g, @@ -318,6 +606,198 @@ void MergeXRGBRow_RVV(const uint8_t* src_r, } while (w > 0); } +struct RgbConstants { + uint8_t kRGBToY[4]; + uint16_t kAddY; + uint16_t pad; +}; + +// RGB to JPeg coefficients +// B * 0.1140 coefficient = 29 +// G * 0.5870 coefficient = 150 +// R * 0.2990 coefficient = 77 +// Add 0.5 = 0x80 +static const struct RgbConstants kRgb24JPEGConstants = {{29, 150, 77, 0}, + 128, + 0}; + +static const struct RgbConstants kRawJPEGConstants = {{77, 150, 29, 0}, 128, 0}; + +// RGB to BT.601 coefficients +// B * 0.1016 coefficient = 25 +// G * 0.5078 coefficient = 129 +// R * 0.2578 coefficient = 66 +// Add 16.5 = 0x1080 + +static const struct RgbConstants kRgb24I601Constants = {{25, 129, 66, 0}, + 0x1080, + 0}; + +static const struct RgbConstants kRawI601Constants = {{66, 129, 25, 0}, + 0x1080, + 0}; + +// ARGB expects first 3 values to contain RGB and 4th value is ignored. +void ARGBToYMatrixRow_RVV(const uint8_t* src_argb, + uint8_t* dst_y, + int width, + const struct RgbConstants* rgbconstants) { + assert(width != 0); + size_t w = (size_t)width; + vuint8m2_t v_by, v_gy, v_ry; // vectors are to store RGBToY constant + vuint16m4_t v_addy; // vector is to store kAddY + size_t vl = __riscv_vsetvl_e8m2(w); + v_by = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[0], vl); + v_gy = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[1], vl); + v_ry = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[2], vl); + v_addy = __riscv_vmv_v_x_u16m4(rgbconstants->kAddY, vl); + do { + vuint8m2_t v_b, v_g, v_r, v_a, v_y; + vuint16m4_t v_y_u16; + size_t vl = __riscv_vsetvl_e8m2(w); + __riscv_vlseg4e8_v_u8m2(&v_b, &v_g, &v_r, &v_a, src_argb, vl); + v_y_u16 = __riscv_vwmulu_vv_u16m4(v_r, v_ry, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_gy, v_g, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_by, v_b, vl); + v_y_u16 = __riscv_vadd_vv_u16m4(v_y_u16, v_addy, vl); + v_y = __riscv_vnsrl_wx_u8m2(v_y_u16, 8, vl); + __riscv_vse8_v_u8m2(dst_y, v_y, vl); + w -= vl; + src_argb += 4 * vl; + dst_y += vl; + } while (w > 0); +} + +void ARGBToYRow_RVV(const uint8_t* src_argb, uint8_t* dst_y, int width) { + ARGBToYMatrixRow_RVV(src_argb, dst_y, width, &kRgb24I601Constants); +} + +void ARGBToYJRow_RVV(const uint8_t* src_argb, uint8_t* dst_yj, int width) { + ARGBToYMatrixRow_RVV(src_argb, dst_yj, width, &kRgb24JPEGConstants); +} + +void ABGRToYRow_RVV(const uint8_t* src_abgr, uint8_t* dst_y, int width) { + ARGBToYMatrixRow_RVV(src_abgr, dst_y, width, &kRawI601Constants); +} + +void ABGRToYJRow_RVV(const uint8_t* src_abgr, uint8_t* dst_yj, int width) { + ARGBToYMatrixRow_RVV(src_abgr, dst_yj, width, &kRawJPEGConstants); +} + +// RGBA expects first value to be A and ignored, then 3 values to contain RGB. +void RGBAToYMatrixRow_RVV(const uint8_t* src_rgba, + uint8_t* dst_y, + int width, + const struct RgbConstants* rgbconstants) { + assert(width != 0); + size_t w = (size_t)width; + vuint8m2_t v_by, v_gy, v_ry; // vectors are to store RGBToY constant + vuint16m4_t v_addy; // vector is to store kAddY + size_t vl = __riscv_vsetvl_e8m2(w); + v_by = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[0], vl); + v_gy = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[1], vl); + v_ry = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[2], vl); + v_addy = __riscv_vmv_v_x_u16m4(rgbconstants->kAddY, vl); + do { + vuint8m2_t v_b, v_g, v_r, v_a, v_y; + vuint16m4_t v_y_u16; + size_t vl = __riscv_vsetvl_e8m2(w); + __riscv_vlseg4e8_v_u8m2(&v_a, &v_b, &v_g, &v_r, src_rgba, vl); + v_y_u16 = __riscv_vwmulu_vv_u16m4(v_r, v_ry, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_gy, v_g, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_by, v_b, vl); + v_y_u16 = __riscv_vadd_vv_u16m4(v_y_u16, v_addy, vl); + v_y = __riscv_vnsrl_wx_u8m2(v_y_u16, 8, vl); + __riscv_vse8_v_u8m2(dst_y, v_y, vl); + w -= vl; + src_rgba += 4 * vl; + dst_y += vl; + } while (w > 0); +} + +void RGBAToYRow_RVV(const uint8_t* src_rgba, uint8_t* dst_y, int width) { + RGBAToYMatrixRow_RVV(src_rgba, dst_y, width, &kRgb24I601Constants); +} + +void RGBAToYJRow_RVV(const uint8_t* src_rgba, uint8_t* dst_yj, int width) { + RGBAToYMatrixRow_RVV(src_rgba, dst_yj, width, &kRgb24JPEGConstants); +} + +void BGRAToYRow_RVV(const uint8_t* src_bgra, uint8_t* dst_y, int width) { + RGBAToYMatrixRow_RVV(src_bgra, dst_y, width, &kRawI601Constants); +} + +void RGBToYMatrixRow_RVV(const uint8_t* src_rgb, + uint8_t* dst_y, + int width, + const struct RgbConstants* rgbconstants) { + assert(width != 0); + size_t w = (size_t)width; + vuint8m2_t v_by, v_gy, v_ry; // vectors are to store RGBToY constant + vuint16m4_t v_addy; // vector is to store kAddY + size_t vl = __riscv_vsetvl_e8m2(w); + v_by = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[0], vl); + v_gy = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[1], vl); + v_ry = __riscv_vmv_v_x_u8m2(rgbconstants->kRGBToY[2], vl); + v_addy = __riscv_vmv_v_x_u16m4(rgbconstants->kAddY, vl); + do { + vuint8m2_t v_b, v_g, v_r, v_y; + vuint16m4_t v_y_u16; + size_t vl = __riscv_vsetvl_e8m2(w); + __riscv_vlseg3e8_v_u8m2(&v_b, &v_g, &v_r, src_rgb, vl); + v_y_u16 = __riscv_vwmulu_vv_u16m4(v_r, v_ry, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_gy, v_g, vl); + v_y_u16 = __riscv_vwmaccu_vv_u16m4(v_y_u16, v_by, v_b, vl); + v_y_u16 = __riscv_vadd_vv_u16m4(v_y_u16, v_addy, vl); + v_y = __riscv_vnsrl_wx_u8m2(v_y_u16, 8, vl); + __riscv_vse8_v_u8m2(dst_y, v_y, vl); + w -= vl; + src_rgb += 3 * vl; + dst_y += vl; + } while (w > 0); +} + +void RGB24ToYJRow_RVV(const uint8_t* src_rgb24, uint8_t* dst_yj, int width) { + RGBToYMatrixRow_RVV(src_rgb24, dst_yj, width, &kRgb24JPEGConstants); +} + +void RAWToYJRow_RVV(const uint8_t* src_raw, uint8_t* dst_yj, int width) { + RGBToYMatrixRow_RVV(src_raw, dst_yj, width, &kRawJPEGConstants); +} + +void RGB24ToYRow_RVV(const uint8_t* src_rgb24, uint8_t* dst_y, int width) { + RGBToYMatrixRow_RVV(src_rgb24, dst_y, width, &kRgb24I601Constants); +} + +void RAWToYRow_RVV(const uint8_t* src_raw, uint8_t* dst_y, int width) { + RGBToYMatrixRow_RVV(src_raw, dst_y, width, &kRawI601Constants); +} + +void ARGBAttenuateRow_RVV(const uint8_t* src_argb, + uint8_t* dst_argb, + int width) { + size_t w = (size_t)width; + // To match behavior on other platforms, vxrm (fixed-point rounding mode + // register) is set to round-to-nearest-up(0). + asm volatile("csrwi vxrm, 0"); + do { + vuint8m2_t v_b, v_g, v_r, v_a; + vuint16m4_t v_ba_16, v_ga_16, v_ra_16; + size_t vl = __riscv_vsetvl_e8m2(w); + __riscv_vlseg4e8_v_u8m2(&v_b, &v_g, &v_r, &v_a, src_argb, vl); + v_ba_16 = __riscv_vwmulu_vv_u16m4(v_b, v_a, vl); + v_ga_16 = __riscv_vwmulu_vv_u16m4(v_g, v_a, vl); + v_ra_16 = __riscv_vwmulu_vv_u16m4(v_r, v_a, vl); + v_b = __riscv_vnclipu_wx_u8m2(v_ba_16, 8, vl); + v_g = __riscv_vnclipu_wx_u8m2(v_ga_16, 8, vl); + v_r = __riscv_vnclipu_wx_u8m2(v_ra_16, 8, vl); + __riscv_vsseg4e8_v_u8m2(dst_argb, v_b, v_g, v_r, v_a, vl); + w -= vl; + src_argb += vl * 4; + dst_argb += vl * 4; + } while (w > 0); +} + #ifdef __cplusplus } // extern "C" } // namespace libyuv diff --git a/libfenrir/src/main/jni/animation/libyuv/source/row_win.cc b/libfenrir/src/main/jni/animation/libyuv/source/row_win.cc index c5a14f86f..b414d2d0e 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/row_win.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/row_win.cc @@ -14,7 +14,9 @@ #if !defined(LIBYUV_DISABLE_X86) && defined(_MSC_VER) && \ !defined(__clang__) && (defined(_M_IX86) || defined(_M_X64)) -#if defined(_M_X64) +#if defined(_M_ARM64EC) +#include +#elif defined(_M_X64) #include #include // For _mm_maddubs_epi16 #endif @@ -3461,17 +3463,14 @@ __declspec(naked) void MergeUVRow_AVX2(const uint8_t* src_u, sub edx, eax convertloop: - vmovdqu ymm0, [eax] // read 32 U's - vmovdqu ymm1, [eax + edx] // and 32 V's - lea eax, [eax + 32] - vpunpcklbw ymm2, ymm0, ymm1 // low 16 UV pairs. mutated qqword 0,2 - vpunpckhbw ymm0, ymm0, ymm1 // high 16 UV pairs. mutated qqword 1,3 - vextractf128 [edi], ymm2, 0 // bytes 0..15 - vextractf128 [edi + 16], ymm0, 0 // bytes 16..31 - vextractf128 [edi + 32], ymm2, 1 // bytes 32..47 - vextractf128 [edi + 48], ymm0, 1 // bytes 47..63 - lea edi, [edi + 64] - sub ecx, 32 + vpmovzxbw ymm0, [eax] + vpmovzxbw ymm1, [eax + edx] + lea eax, [eax + 16] + vpsllw ymm1, ymm1, 8 + vpor ymm2, ymm1, ymm0 + vmovdqu [edi], ymm2 + lea edi, [edi + 32] + sub ecx, 16 jg convertloop pop edi diff --git a/libfenrir/src/main/jni/animation/libyuv/source/scale_argb.cc b/libfenrir/src/main/jni/animation/libyuv/source/scale_argb.cc index 3e6f54776..8d2509474 100644 --- a/libfenrir/src/main/jni/animation/libyuv/source/scale_argb.cc +++ b/libfenrir/src/main/jni/animation/libyuv/source/scale_argb.cc @@ -659,6 +659,14 @@ static void ScaleYUVToARGBBilinearUp(int src_width, } } #endif +#if defined(HAS_I422TOARGBROW_LSX) + if (TestCpuFlag(kCpuHasLSX)) { + I422ToARGBRow = I422ToARGBRow_Any_LSX; + if (IS_ALIGNED(src_width, 16)) { + I422ToARGBRow = I422ToARGBRow_LSX; + } + } +#endif #if defined(HAS_I422TOARGBROW_LASX) if (TestCpuFlag(kCpuHasLASX)) { I422ToARGBRow = I422ToARGBRow_Any_LASX; @@ -667,6 +675,11 @@ static void ScaleYUVToARGBBilinearUp(int src_width, } } #endif +#if defined(HAS_I422TOARGBROW_RVV) + if (TestCpuFlag(kCpuHasRVV)) { + I422ToARGBRow = I422ToARGBRow_RVV; + } +#endif void (*InterpolateRow)(uint8_t* dst_argb, const uint8_t* src_argb, ptrdiff_t src_stride, int dst_width, diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/arch.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/arch.h index 08b07db59..3845c3a08 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/arch.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/arch.h @@ -73,6 +73,9 @@ __attribute__((noreturn)) void celt_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); +#if defined(_MSC_VER) + _set_abort_behavior( 0, _WRITE_ABORT_MSG); +#endif abort(); } #endif diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/armcpu.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/armcpu.c index 694a63b78..c7d16e6d6 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/armcpu.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/armcpu.c @@ -93,6 +93,8 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ #elif defined(__linux__) /* Linux based */ +#include + opus_uint32 opus_cpu_capabilities(void) { opus_uint32 flags = 0; @@ -154,7 +156,7 @@ opus_uint32 opus_cpu_capabilities(void) "your platform. Reconfigure with --disable-rtcd (or send patches)." #endif -int opus_select_arch(void) +static int opus_select_arch_impl(void) { opus_uint32 flags = opus_cpu_capabilities(); int arch = 0; @@ -182,4 +184,11 @@ int opus_select_arch(void) return arch; } +int opus_select_arch(void) { + int arch = opus_select_arch_impl(); +#ifdef FUZZING + arch = rand()%(arch+1); +#endif + return arch; +} #endif diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/pitch_neon_intr.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/pitch_neon_intr.c index 1ac38c433..35cc46e2c 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/pitch_neon_intr.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/arm/pitch_neon_intr.c @@ -137,22 +137,27 @@ void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus /* celt_inner_prod_neon_float_c_simulation() simulates the floating-point */ /* operations of celt_inner_prod_neon(), and both functions should have bit */ /* exact output. */ -static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, int N) +static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, float *err, int N) { int i; + *err = 0; opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0; for (i = 0; i < N - 3; i += 4) { xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]); xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]); xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]); xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]); + *err += ABS32(xy0)+ABS32(xy1)+ABS32(xy2)+ABS32(xy3); } xy0 += xy2; xy1 += xy3; xy = xy0 + xy1; + *err += ABS32(xy1)+ABS32(xy0)+ABS32(xy); for (; i < N; i++) { xy = MAC16_16(xy, x[i], y[i]); + *err += ABS32(xy); } + *err = *err*2e-7 + N*1e-37; return xy; } @@ -160,32 +165,10 @@ static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, c /* operations of dual_inner_prod_neon(), and both functions should have bit */ /* exact output. */ static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, - int N, opus_val32 *xy1, opus_val32 *xy2) + int N, opus_val32 *xy1, opus_val32 *xy2, float *err) { - int i; - opus_val32 xy01, xy02, xy01_0 = 0, xy01_1 = 0, xy01_2 = 0, xy01_3 = 0, xy02_0 = 0, xy02_1 = 0, xy02_2 = 0, xy02_3 = 0; - for (i = 0; i < N - 3; i += 4) { - xy01_0 = MAC16_16(xy01_0, x[i + 0], y01[i + 0]); - xy01_1 = MAC16_16(xy01_1, x[i + 1], y01[i + 1]); - xy01_2 = MAC16_16(xy01_2, x[i + 2], y01[i + 2]); - xy01_3 = MAC16_16(xy01_3, x[i + 3], y01[i + 3]); - xy02_0 = MAC16_16(xy02_0, x[i + 0], y02[i + 0]); - xy02_1 = MAC16_16(xy02_1, x[i + 1], y02[i + 1]); - xy02_2 = MAC16_16(xy02_2, x[i + 2], y02[i + 2]); - xy02_3 = MAC16_16(xy02_3, x[i + 3], y02[i + 3]); - } - xy01_0 += xy01_2; - xy02_0 += xy02_2; - xy01_1 += xy01_3; - xy02_1 += xy02_3; - xy01 = xy01_0 + xy01_1; - xy02 = xy02_0 + xy02_1; - for (; i < N; i++) { - xy01 = MAC16_16(xy01, x[i], y01[i]); - xy02 = MAC16_16(xy02, x[i], y02[i]); - } - *xy1 = xy01; - *xy2 = xy02; + *xy1 = celt_inner_prod_neon_float_c_simulation(x, y01, &err[0], N); + *xy2 = celt_inner_prod_neon_float_c_simulation(x, y02, &err[1], N); } #endif /* OPUS_CHECK_ASM */ @@ -225,7 +208,12 @@ opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N) } #ifdef OPUS_CHECK_ASM - celt_assert(ABS32(celt_inner_prod_neon_float_c_simulation(x, y, N) - xy) <= VERY_SMALL); + { + float err, res; + res = celt_inner_prod_neon_float_c_simulation(x, y, &err, N); + /*if (ABS32(res - xy) > err) fprintf(stderr, "%g %g %g\n", res, xy, err);*/ + celt_assert(ABS32(res - xy) <= err); + } #endif return xy; @@ -280,9 +268,12 @@ void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus #ifdef OPUS_CHECK_ASM { opus_val32 xy1_c, xy2_c; - dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c); - celt_assert(ABS32(xy1_c - *xy1) <= VERY_SMALL); - celt_assert(ABS32(xy2_c - *xy2) <= VERY_SMALL); + float err[2]; + dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c, err); + /*if (ABS32(xy1_c - *xy1) > err[0]) fprintf(stderr, "dual1 fail: %g %g %g\n", xy1_c, *xy1, err[0]); + if (ABS32(xy2_c - *xy2) > err[1]) fprintf(stderr, "dual2 fail: %g %g %g\n", xy2_c, *xy2, err[1]);*/ + celt_assert(ABS32(xy1_c - *xy1) <= err[0]); + celt_assert(ABS32(xy2_c - *xy2) <= err[1]); } #endif } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/bands.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/bands.c index 2702963c3..5320ffab0 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/bands.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/bands.c @@ -901,7 +901,7 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, sctx->itheta = itheta; sctx->qalloc = qalloc; } -static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, +static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, celt_norm *lowband_out) { int c; @@ -926,7 +926,6 @@ static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, sign = ec_dec_bits(ec, 1); } ctx->remaining_bits -= 1<resynth) x[0] = sign ? -NORM_SCALING : NORM_SCALING; @@ -1134,7 +1133,7 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, /* Special case for one sample */ if (N==1) { - return quant_band_n1(ctx, X, NULL, b, lowband_out); + return quant_band_n1(ctx, X, NULL, lowband_out); } if (tf_change>0) @@ -1256,7 +1255,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm /* Special case for one sample */ if (N==1) { - return quant_band_n1(ctx, X, Y, b, lowband_out); + return quant_band_n1(ctx, X, Y, lowband_out); } orig_fill = fill; @@ -1381,6 +1380,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm return cm; } +#ifndef DISABLE_UPDATE_DRAFT static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm *norm2, int start, int M, int dual_stereo) { int n1, n2; @@ -1393,6 +1393,7 @@ static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm if (dual_stereo) OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1); } +#endif void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_decoder.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_decoder.c index e6efce935..883dae15d 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_decoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_decoder.c @@ -90,7 +90,7 @@ struct OpusCustomDecoder { opus_uint32 rng; int error; int last_pitch_index; - int loss_count; + int loss_duration; int skip_plc; int postfilter_period; int postfilter_period_old; @@ -117,13 +117,19 @@ void validate_celt_decoder(CELTDecoder *st) #ifndef CUSTOM_MODES celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL)); celt_assert(st->overlap == 120); + celt_assert(st->end <= 21); +#else +/* From Section 4.3 in the spec: "The normal CELT layer uses 21 of those bands, + though Opus Custom (see Section 6.2) may use a different number of bands" + + Check if it's within the maximum number of Bark frequency bands instead */ + celt_assert(st->end <= 25); #endif celt_assert(st->channels == 1 || st->channels == 2); celt_assert(st->stream_channels == 1 || st->stream_channels == 2); celt_assert(st->downsample > 0); celt_assert(st->start == 0 || st->start == 17); celt_assert(st->start < st->end); - celt_assert(st->end <= 21); #ifdef OPUS_ARCHMASK celt_assert(st->arch >= 0); celt_assert(st->arch <= OPUS_ARCHMASK); @@ -506,7 +512,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) int nbEBands; int overlap; int start; - int loss_count; + int loss_duration; int noise_based; const opus_int16 *eBands; SAVE_STACK; @@ -526,9 +532,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) oldLogE2 = oldLogE + 2*nbEBands; backgroundLogE = oldLogE2 + 2*nbEBands; - loss_count = st->loss_count; + loss_duration = st->loss_duration; start = st->start; - noise_based = loss_count >= 5 || start != 0 || st->skip_plc; + noise_based = loss_duration >= 40 || start != 0 || st->skip_plc; if (noise_based) { /* Noise-based PLC/CNG */ @@ -551,9 +557,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) #else ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ #endif + c=0; do { + OPUS_MOVE(decode_mem[c], decode_mem[c]+N, + DECODE_BUFFER_SIZE-N+(overlap>>1)); + } while (++crng = seed; - c=0; do { - OPUS_MOVE(decode_mem[c], decode_mem[c]+N, - DECODE_BUFFER_SIZE-N+(overlap>>1)); - } while (++cdownsample, 0, st->arch); } else { int exc_length; @@ -596,7 +601,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) VARDECL(opus_val16, _exc); VARDECL(opus_val16, fir_tmp); - if (loss_count == 0) + if (loss_duration == 0) { st->last_pitch_index = pitch_index = celt_plc_pitch_search(decode_mem, C, st->arch); } else { @@ -624,9 +629,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM) buf = decode_mem[c]; for (i=0;iloss_count = loss_count+1; + /* Saturate to soemthing large to avoid wrap-around. */ + st->loss_duration = IMIN(10000, loss_duration+(1<skip_plc = st->loss_count != 0; + st->skip_plc = st->loss_duration != 0; if (dec == NULL) { @@ -1134,25 +1141,21 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat if (C==1) OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands); - /* In case start or end were to change */ if (!isTransient) { - opus_val16 max_background_increase; OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); - /* In normal circumstances, we only allow the noise floor to increase by - up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB - increase for each update.*/ - if (st->loss_count < 10) - max_background_increase = M*QCONST16(0.001f,DB_SHIFT); - else - max_background_increase = QCONST16(1.f,DB_SHIFT); - for (i=0;i<2*nbEBands;i++) - backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); } else { for (i=0;i<2*nbEBands;i++) oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); } + /* In normal circumstances, we only allow the noise floor to increase by + up to 2.4 dB/second, but when we're in DTX we give the weight of + all missing packets to the update packet. */ + max_background_increase = IMIN(160, st->loss_duration+M)*QCONST16(0.001f,DB_SHIFT); + for (i=0;i<2*nbEBands;i++) + backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); + /* In case start or end were to change */ c=0; do { for (i=0;irng = dec->rng; deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, accum); - st->loss_count = 0; + st->loss_duration = 0; RESTORE_STACK; if (ec_tell(dec) > 8*len) return OPUS_INTERNAL_ERROR; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_encoder.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_encoder.c index 44cb0850a..637d442cf 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_encoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/celt_encoder.c @@ -1571,7 +1571,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling)); effectiveBytes = nbCompressedBytes - nbFilledBytes; } - equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50); + equiv_rate = ((opus_int32)nbCompressedBytes*8*50 << (3-LM)) - (40*C+20)*((400>>LM) - 50); if (st->bitrate != OPUS_BITRATE_MAX) equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50)); @@ -1719,8 +1719,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch); compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); amp2Log2(mode, effEnd, end, bandE, bandLogE2, C); - for (i=0;iupsample, st->arch); @@ -1856,8 +1859,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch); amp2Log2(mode, effEnd, end, bandE, bandLogE, C); /* Compensate for the scaling of short vs long mdcts */ - for (i=0;i 1e-10f) +#endif { for (i = 0; i < p; i++) { /* Sum up this iteration's reflection coefficient */ opus_val32 rr = 0; for (j = 0; j < i; j++) rr += MULT32_32_Q31(lpc[j],ac[i - j]); - rr += SHR32(ac[i + 1],3); - r = -frac_div32(SHL32(rr,3), error); + rr += SHR32(ac[i + 1],6); + r = -frac_div32(SHL32(rr,6), error); /* Update LPC coefficients and total error */ - lpc[i] = SHR32(r,3); + lpc[i] = SHR32(r,6); for (j = 0; j < (i+1)>>1; j++) { opus_val32 tmp1, tmp2; @@ -73,17 +77,61 @@ int p error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); /* Bail out once we get 30 dB gain */ #ifdef FIXED_POINT - if (error maxabs) { + maxabs = absval; + idx = i; + } + } + maxabs = PSHR32(maxabs, 13); /* Q25->Q12 */ + + if (maxabs > 32767) { + maxabs = MIN32(maxabs, 163838); + chirp_Q16 = QCONST32(0.999, 16) - DIV32(SHL32(maxabs - 32767, 14), + SHR32(MULT32_32_32(maxabs, idx + 1), 2)); + chirp_minus_one_Q16 = chirp_Q16 - 65536; + + /* Apply bandwidth expansion. */ + for (i = 0; i < p - 1; i++) { + lpc[i] = MULT32_32_Q16(chirp_Q16, lpc[i]); + chirp_Q16 += PSHR32(MULT32_32_32(chirp_Q16, chirp_minus_one_Q16), 16); + } + lpc[p - 1] = MULT32_32_Q16(chirp_Q16, lpc[p - 1]); + } else { + break; + } + } + + if (iter == 10) { + /* If the coeffs still do not fit into the 16 bit range after 10 iterations, + fall back to the A(z)=1 filter. */ + OPUS_CLEAR(lpc, p); + _lpc[0] = 4096; /* Q12 */ + } else { + for (i = 0; i < p; i++) { + _lpc[i] = EXTRACT16(PSHR32(lpc[i], 13)); /* Q25->Q12 */ + } + } + } #endif } @@ -111,17 +159,17 @@ void celt_fir_c( sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT); sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT); xcorr_kernel(rnum, x+i-ord, sum, ord, arch); - y[i ] = ROUND16(sum[0], SIG_SHIFT); - y[i+1] = ROUND16(sum[1], SIG_SHIFT); - y[i+2] = ROUND16(sum[2], SIG_SHIFT); - y[i+3] = ROUND16(sum[3], SIG_SHIFT); + y[i ] = SROUND16(sum[0], SIG_SHIFT); + y[i+1] = SROUND16(sum[1], SIG_SHIFT); + y[i+2] = SROUND16(sum[2], SIG_SHIFT); + y[i+3] = SROUND16(sum[3], SIG_SHIFT); } for (;i= 1400) +#if defined(_MSC_VER) && (_MSC_VER >= 1910) +# include /* Improve compiler throughput. */ +#else # include +#endif /*In _DEBUG mode this is not an intrinsic by default.*/ # pragma intrinsic(_BitScanReverse) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_debug.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_debug.h index f43529523..ef2e5d02f 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_debug.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_debug.h @@ -167,7 +167,7 @@ static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line) #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) { - int res; + opus_int32 res; if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) { fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); @@ -175,7 +175,7 @@ static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) celt_assert(0); #endif } - res = a<> 16; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT32_32_Q16: output is not int: %lld*%lld=%lld\n", (long long)a, (long long)b, (long long)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=5; + return res; +} + #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__) static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line) { @@ -446,7 +491,7 @@ static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int celt_assert(0); #endif } - if (ABS32(b)>=((opus_val32)(1)<<(15+Q))) + if (ABS32(b)>=((opus_int64)(1)<<(16+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -479,7 +524,7 @@ static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int celt_assert(0); #endif } - if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) + if (ABS32(b)>=((opus_int64)(1)<<(16+Q))) { fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); #ifdef FIXED_DEBUG_ASSERT @@ -786,6 +831,6 @@ static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x) #undef PRINT_MIPS -#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); +#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", (unsigned long long)celt_mips);} while (0); #endif diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_generic.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_generic.h index 5f4abda76..8f29d46bb 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_generic.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/fixed_generic.h @@ -57,6 +57,13 @@ #define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) #endif +/** 32x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#if OPUS_FAST_INT64 +#define MULT32_32_Q16(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),16)) +#else +#define MULT32_32_Q16(a,b) (ADD32(ADD32(ADD32((opus_val32)(SHR32(((opus_uint32)((a)&0x0000ffff)*(opus_uint32)((b)&0x0000ffff)),16)), MULT16_16SU(SHR32(a,16),((b)&0x0000ffff))), MULT16_16SU(SHR32(b,16),((a)&0x0000ffff))), SHL32(MULT16_16(SHR32(a,16),SHR32(b,16)),16))) +#endif + /** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ #if OPUS_FAST_INT64 #define MULT32_32_Q31(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),31)) @@ -102,9 +109,9 @@ #define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x))) -/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ +/** Shift by a and round-to-nearest 32-bit value. Result is a 16-bit value */ #define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) -/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */ +/** Shift by a and round-to-nearest 32-bit value. Result is a saturated 16-bit value */ #define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767)); /** Divide by two */ @@ -131,6 +138,9 @@ /** 16x16 multiplication where the result fits in 16 bits */ #define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) +/** 32x32 multiplication where the result fits in 32 bits */ +#define MULT32_32_32(a,b) ((((opus_val32)(a))*((opus_val32)(b)))) + /* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */ /** 16x16 multiplication where the result fits in 32 bits */ #define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b))) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/float_cast.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/float_cast.h index 889dae965..8915a5fd7 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/float_cast.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/float_cast.h @@ -67,7 +67,39 @@ #include static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));} -#elif defined(HAVE_LRINTF) +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) + + #include + static OPUS_INLINE opus_int32 float2int(float value) + { + /* _mm_load_ss will generate same code as _mm_set_ss + ** in _MSC_VER >= 1914 /02 so keep __mm_load__ss + ** for backward compatibility. + */ + return _mm_cvtss_si32(_mm_load_ss(&value)); + } + +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86) + + #include + + /* Win32 doesn't seem to have these functions. + ** Therefore implement OPUS_INLINE versions of these functions here. + */ + + static OPUS_INLINE opus_int32 + float2int (float flt) + { int intgr; + + _asm + { fld flt + fistp intgr + } ; + + return intgr ; + } + +#elif defined(HAVE_LRINTF) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* These defines enable functionality introduced with the 1999 ISO C ** standard. They must be defined before the inclusion of math.h to @@ -85,7 +117,7 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s #include #define float2int(x) lrintf(x) -#elif (defined(HAVE_LRINT)) +#elif defined(HAVE_LRINT) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 @@ -96,32 +128,6 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s #include #define float2int(x) lrint(x) -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1)) - #include - - static __inline long int float2int(float value) - { - return _mm_cvtss_si32(_mm_load_ss(&value)); - } -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86) - #include - - /* Win32 doesn't seem to have these functions. - ** Therefore implement OPUS_INLINE versions of these functions here. - */ - - static __inline long int - float2int (float flt) - { int intgr; - - _asm - { fld flt - fistp intgr - } ; - - return intgr ; - } - #else #if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/kiss_fft.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/kiss_fft.h index bffa2bfad..267f72f99 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/kiss_fft.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/kiss_fft.h @@ -52,6 +52,10 @@ extern "C" { # define kiss_fft_scalar opus_int32 # define kiss_twiddle_scalar opus_int16 +/* Some 32-bit CPUs would load/store a kiss_twiddle_cpx with a single memory + * access, and could benefit from additional alignment. + */ +# define KISS_TWIDDLE_CPX_ALIGNMENT (sizeof(opus_int32)) #else # ifndef kiss_fft_scalar @@ -62,6 +66,12 @@ extern "C" { # endif #endif +#if defined(__GNUC__) && defined(KISS_TWIDDLE_CPX_ALIGNMENT) +#define KISS_TWIDDLE_CPX_ALIGNED __attribute__((aligned(KISS_TWIDDLE_CPX_ALIGNMENT))) +#else +#define KISS_TWIDDLE_CPX_ALIGNED +#endif + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; @@ -70,7 +80,7 @@ typedef struct { typedef struct { kiss_twiddle_scalar r; kiss_twiddle_scalar i; -}kiss_twiddle_cpx; +} KISS_TWIDDLE_CPX_ALIGNED kiss_twiddle_cpx; #define MAXFACTORS 8 /* e.g. an fft of length 128 has 4 factors diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/mathops.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/mathops.h index 5e86ff0dd..478ac9187 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/mathops.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/mathops.h @@ -137,7 +137,7 @@ static OPUS_INLINE float celt_log2(float x) } in; in.f = x; integer = (in.i>>23)-127; - in.i -= integer<<23; + in.i -= (opus_uint32)integer<<23; frac = in.f - 1.5f; frac = -0.41445418f + frac*(0.95909232f + frac*(-0.33951290f + frac*0.16541097f)); @@ -153,14 +153,14 @@ static OPUS_INLINE float celt_exp2(float x) float f; opus_uint32 i; } res; - integer = floor(x); + integer = (int)floor(x); if (integer < -50) return 0; frac = x-integer; /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ res.f = 0.99992522f + frac * (0.69583354f + frac * (0.22606716f + 0.078024523f*frac)); - res.i = (res.i + (integer<<23)) & 0x7fffffff; + res.i = (res.i + ((opus_uint32)integer<<23)) & 0x7fffffff; return res.f; } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/modes.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/modes.c index 390c5e8ae..23f7cde66 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/modes.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/modes.c @@ -173,7 +173,10 @@ static void compute_allocation_table(CELTMode *mode) mode->nbAllocVectors = BITALLOC_SIZE; allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); if (allocVectors==NULL) + { + mode->allocVectors = NULL; return; + } /* Check for standard mode */ if (mode->Fs == 400*(opus_int32)mode->shortMdctSize) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/os_support.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/os_support.h index a2171971e..009bf861d 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/os_support.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/os_support.h @@ -39,7 +39,6 @@ #include "opus_defines.h" #include -#include #include /** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/pitch.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/pitch.c index 872582a48..7998db416 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/pitch.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/pitch.c @@ -161,17 +161,26 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x shift=0; if (C==2) shift++; -#endif for (i=1;i>1;i++) - x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); - x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); + x_lp[i] = SHR32(x[0][(2*i-1)], shift+2) + SHR32(x[0][(2*i+1)], shift+2) + SHR32(x[0][2*i], shift+1); + x_lp[0] = SHR32(x[0][1], shift+2) + SHR32(x[0][0], shift+1); if (C==2) { for (i=1;i>1;i++) - x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); - x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); + x_lp[i] += SHR32(x[1][(2*i-1)], shift+2) + SHR32(x[1][(2*i+1)], shift+2) + SHR32(x[1][2*i], shift+1); + x_lp[0] += SHR32(x[1][1], shift+2) + SHR32(x[1][0], shift+1); } - +#else + for (i=1;i>1;i++) + x_lp[i] = .25f*x[0][(2*i-1)] + .25f*x[0][(2*i+1)] + .5f*x[0][2*i]; + x_lp[0] = .25f*x[0][1] + .5f*x[0][0]; + if (C==2) + { + for (i=1;i>1;i++) + x_lp[i] += .25f*x[1][(2*i-1)] + .25f*x[1][(2*i+1)] + .5f*x[1][2*i]; + x_lp[0] += .25f*x[1][1] + .5f*x[1][0]; + } +#endif _celt_autocorr(x_lp, ac, NULL, 0, 4, len>>1, arch); @@ -249,7 +258,7 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 maxcorr=1; #endif celt_assert(max_pitch>0); - celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); + celt_sig_assert(((size_t)_x&3)==0); for (i=0;i (depth_threshold*band_width<>4 && j<=signalBandwidth)) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/stack_alloc.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/stack_alloc.h index 2b51c8d80..ae40e2a16 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/stack_alloc.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/stack_alloc.h @@ -40,7 +40,7 @@ #endif #ifdef USE_ALLOCA -# ifdef WIN32 +# ifdef _WIN32 # include # else # ifdef HAVE_ALLOCA_H @@ -102,7 +102,7 @@ #define VARDECL(type, var) type *var -# ifdef WIN32 +# ifdef _WIN32 # define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) # else # define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/celt_lpc_sse.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/celt_lpc_sse.h index 7d1ecf753..90e69ecf6 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/celt_lpc_sse.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/celt_lpc_sse.h @@ -33,7 +33,6 @@ #endif #if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT) -#define OVERRIDE_CELT_FIR void celt_fir_sse4_1( const opus_val16 *x, @@ -44,10 +43,11 @@ void celt_fir_sse4_1( int arch); #if defined(OPUS_X86_PRESUME_SSE4_1) +#define OVERRIDE_CELT_FIR #define celt_fir(x, num, y, N, ord, arch) \ ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, arch)) -#else +#elif defined(OPUS_HAVE_RTCD) extern void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])( const opus_val16 *x, @@ -57,6 +57,7 @@ extern void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])( int ord, int arch); +#define OVERRIDE_CELT_FIR # define celt_fir(x, num, y, N, ord, arch) \ ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, arch)) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse.h b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse.h index e5f87ab51..964aef50d 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse.h @@ -63,7 +63,7 @@ void xcorr_kernel_sse( #define xcorr_kernel(x, y, sum, len, arch) \ ((void)arch, xcorr_kernel_sse(x, y, sum, len)) -#elif (defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)) || (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) +#elif defined(OPUS_HAVE_RTCD) && ((defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)) || (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))) extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])( const opus_val16 *x, @@ -91,7 +91,7 @@ opus_val32 celt_inner_prod_sse2( int N); #endif -#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT) +#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT) opus_val32 celt_inner_prod_sse( const opus_val16 *x, const opus_val16 *y, @@ -115,8 +115,8 @@ opus_val32 celt_inner_prod_sse( ((void)arch, celt_inner_prod_sse(x, y, N)) -#elif ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) || \ - (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) +#elif defined(OPUS_HAVE_RTCD) && (((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) || \ + (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))) extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])( const opus_val16 *x, diff --git a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse4_1.c index a092c68b2..2bc578304 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/celt/x86/pitch_sse4_1.c @@ -117,6 +117,14 @@ void xcorr_kernel_sse4_1(const opus_val16 * x, const opus_val16 * y, opus_val32 __m128i sum0, sum1, sum2, sum3, vecSum; __m128i initSum; +#ifdef OPUS_CHECK_ASM + opus_val32 sum_c[4]; + for (j=0;j<4;j++) { + sum_c[j] = sum[j]; + } + xcorr_kernel_c(x, y, sum_c, len); +#endif + celt_assert(len >= 3); sum0 = _mm_setzero_si128(); @@ -177,19 +185,56 @@ void xcorr_kernel_sse4_1(const opus_val16 * x, const opus_val16 * y, opus_val32 vecSum = _mm_add_epi32(vecSum, sum2); } - for (;jint: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [in] application int: Coding mode (one of @ref OPUS_APPLICATION_VOIP, @ref OPUS_APPLICATION_AUDIO, or @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @param [out] error int*: @ref opus_errorcodes * @note Regardless of the sampling rate and number channels selected, the Opus encoder * can switch to a lower audio bandwidth or number of channels if the bitrate @@ -222,7 +222,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( * This must be one of 8000, 12000, 16000, * 24000, or 48000. * @param [in] channels int: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [in] application int: Coding mode (one of OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO, or OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_encoder_init( diff --git a/libfenrir/src/main/jni/audio/opus/libopus/include/opus_custom.h b/libfenrir/src/main/jni/audio/opus/libopus/include/opus_custom.h index 41f36bf2f..2f22d4b35 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/include/opus_custom.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/include/opus_custom.h @@ -104,7 +104,8 @@ typedef struct OpusCustomDecoder OpusCustomDecoder; /** The mode contains all the information necessary to create an encoder. Both the encoder and decoder need to be initialized with exactly the same mode, otherwise the output will be - corrupted. + corrupted. The mode MUST NOT BE DESTROYED until the encoders and + decoders that use it are destroyed as well. @brief Mode configuration */ typedef struct OpusCustomMode OpusCustomMode; @@ -178,7 +179,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encode ) OPUS_ARG_NONNULL(1); -/** Destroys a an encoder state. +/** Destroys an encoder state. * @param[in] st OpusCustomEncoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); @@ -286,7 +287,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decode int *error ) OPUS_ARG_NONNULL(1); -/** Destroys a an decoder state. +/** Destroys a decoder state. * @param[in] st OpusCustomDecoder*: State to be freed. */ OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/include/opus_defines.h b/libfenrir/src/main/jni/audio/opus/libopus/include/opus_defines.h index d141418b2..94b9e0d9f 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/include/opus_defines.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/include/opus_defines.h @@ -64,7 +64,7 @@ extern "C" { /**Export control for opus functions */ #ifndef OPUS_EXPORT -# if defined(WIN32) +# if defined(_WIN32) # if defined(OPUS_BUILD) && defined(DLL_EXPORT) # define OPUS_EXPORT __declspec(dllexport) # else @@ -482,7 +482,8 @@ extern "C" { * @param[in] x opus_int32: Allowed values: *

*
0
Disable inband FEC (default).
- *
1
Enable inband FEC.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) @@ -491,7 +492,8 @@ extern "C" { * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Inband FEC disabled (default).
- *
1
Inband FEC enabled.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/CNG.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/CNG.c index ef8e38df9..2a910099e 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/CNG.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/CNG.c @@ -118,6 +118,10 @@ void silk_CNG( /* Smooth gains */ for( i = 0; i < psDec->nb_subfr; i++ ) { psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); + /* If the smoothed gain is 3 dB greater than this subframe's gain, use this subframe's gain to adapt faster. */ + if( silk_SMULWW( psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_THRESHOLD_Q16 ) > psDecCtrl->Gains_Q16[ i ] ) { + psCNG->CNG_smth_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; + } } } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/LPC_fit.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/LPC_fit.c index cdea4f3ab..c0690a1fc 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/LPC_fit.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/LPC_fit.c @@ -31,7 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" -/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */ +/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around. + This logic is reused in _celt_lpc(). Any bug fixes should also be applied there. */ void silk_LPC_fit( opus_int16 *a_QOUT, /* O Output signal */ opus_int32 *a_QIN, /* I/O Input signal */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroCount.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroCount.h index 78100ffed..dab2f57a6 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroCount.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroCount.h @@ -27,9 +27,9 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SIGPROCFIX_API_MACROCOUNT_H #define SIGPROCFIX_API_MACROCOUNT_H -#include #ifdef silk_MACRO_COUNT +#include #define varDefine opus_int64 ops_count = 0; extern opus_int64 ops_count; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroDebug.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroDebug.h index 8dd4ce2ee..3110da9a7 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroDebug.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/MacroDebug.h @@ -55,7 +55,7 @@ static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ opus_int32 ret; - ret = a + b; + ret = (opus_int32)((opus_uint32)a + (opus_uint32)b); if ( ret != silk_ADD_SAT32( a, b ) ) { fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); @@ -101,9 +101,9 @@ static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file #undef silk_SUB32 #define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ - opus_int32 ret; + opus_int64 ret; - ret = a - b; + ret = a - (opus_int64)b; if ( ret != silk_SUB_SAT32( a, b ) ) { fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); @@ -257,7 +257,7 @@ static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, c static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ opus_int32 ret; opus_int64 ret64; - ret = a32 * b32; + ret = (opus_int32)((opus_uint32)a32 * (opus_uint32)b32); ret64 = (opus_int64)a32 * (opus_int64)b32; if ( (opus_int64)ret != ret64 ) { @@ -333,8 +333,8 @@ static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char #define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ opus_int32 ret; - ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); - if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) + ret = silk_ADD32_ovflw( a32, silk_SMULWB( b32, c32 ) ); + if ( ret != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) { fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -465,7 +465,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char if ( fail ) { - fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); + fprintf (stderr, "silk_SMULWW(%d, %d) in %s: line %d\n", a32, b32, file, line); #ifdef FIXED_DEBUG_ASSERT silk_assert( 0 ); #endif @@ -491,12 +491,6 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_ return ret; } -/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ -#undef silk_MLA_ovflw -#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) -#undef silk_SMLABB_ovflw -#define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) - /* no checking needed for silk_SMULL no checking needed for silk_SMLAL no checking needed for silk_SMLALBB @@ -546,10 +540,10 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ opus_int8 ret; int fail = 0; - ret = a << shift; + ret = (opus_int8)((opus_uint8)a << shift); fail |= shift < 0; fail |= shift >= 8; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -565,10 +559,10 @@ static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char * static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ opus_int16 ret; int fail = 0; - ret = a << shift; + ret = (opus_int16)((opus_uint16)a << shift); fail |= shift < 0; fail |= shift >= 16; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -584,10 +578,10 @@ static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, cha static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; int fail = 0; - ret = a << shift; + ret = (opus_int32)((opus_uint32)a << shift); fail |= shift < 0; fail |= shift >= 32; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; + fail |= (opus_int64)ret != (opus_int64)(((opus_uint64)a) << shift); if ( fail ) { fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -603,7 +597,7 @@ static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, cha static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ opus_int64 ret; int fail = 0; - ret = a << shift; + ret = (opus_int64)((opus_uint64)a << shift); fail |= shift < 0; fail |= shift >= 64; fail |= (ret>>shift) != ((opus_int64)a); @@ -714,8 +708,8 @@ static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift #define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ opus_int16 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + ret = a + (opus_int16)((opus_uint16)b << shift); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -729,8 +723,8 @@ static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int #define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + ret = silk_ADD32_ovflw(a, (opus_int32)((opus_uint32)b << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -774,7 +768,7 @@ static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int #define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a + (b >> shift); + ret = silk_ADD32_ovflw(a, (b >> shift)); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); @@ -804,8 +798,8 @@ static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 #define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a - (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) + ret = silk_SUB32_ovflw(a, (opus_int32)((opus_uint32)b << shift)); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (opus_int64)(((opus_uint64)b) << shift)) ) { fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); #ifdef FIXED_DEBUG_ASSERT @@ -819,7 +813,7 @@ static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opu #define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ opus_int32 ret; - ret = a - (b >> shift); + ret = silk_SUB32_ovflw(a, (b >> shift)); if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) { fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); @@ -835,7 +829,7 @@ static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opu static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ opus_int32 ret; ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - /* the marco definition can't handle a shift of zero */ + /* the macro definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) { fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); @@ -850,7 +844,7 @@ static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, #define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ opus_int64 ret; - /* the marco definition can't handle a shift of zero */ + /* the macro definition can't handle a shift of zero */ if ( (shift <= 0) || (shift>=64) ) { fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ.c index 1d64d8e25..45dd45ce8 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ.c @@ -75,21 +75,21 @@ static OPUS_INLINE void silk_noise_shape_quantizer( void silk_NSQ_c ( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int k, lag, start_idx, LSF_interpolation_flag; @@ -173,9 +173,9 @@ void silk_NSQ_c RESTORE_STACK; } -/***********************************/ -/* silk_noise_shape_quantizer */ -/***********************************/ +/******************************/ +/* silk_noise_shape_quantizer */ +/******************************/ #if !defined(OPUS_X86_MAY_HAVE_SSE4_1) static OPUS_INLINE @@ -262,7 +262,7 @@ void silk_noise_shape_quantizer( tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ - n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q13 = silk_SMULWB( silk_ADD_SAT32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); shp_lag_ptr++; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ_del_dec.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ_del_dec.c index 3fd9fa0d5..41f3fc93e 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ_del_dec.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/NSQ_del_dec.c @@ -115,21 +115,21 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( ); void silk_NSQ_del_dec_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; @@ -394,8 +394,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SMULWB( silk_ADD_SAT32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { @@ -451,9 +451,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ + tmp1 = silk_ADD_SAT32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ - tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ + tmp1 = silk_SUB_SAT32( tmp2, tmp1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ @@ -535,7 +535,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( /* Update states */ psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); - psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 0 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 0 ].xq_Q14 = xq_Q14; @@ -555,7 +555,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( /* Update states */ psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); - psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 1 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 1 ].xq_Q14 = xq_Q14; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/PLC.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/PLC.c index f89391651..4667440db 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/PLC.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/PLC.c @@ -328,10 +328,8 @@ static OPUS_INLINE void silk_PLC_conceal( for( j = 0; j < LTP_ORDER; j++ ) { B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); } - if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) { - /* Gradually reduce excitation gain */ - rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); - } + /* Gradually reduce excitation gain */ + rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); /* Slowly increase pitch lag */ psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/SigProc_FIX.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/SigProc_FIX.h index f9ae32632..fbdfa82e2 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/SigProc_FIX.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/SigProc_FIX.h @@ -381,7 +381,7 @@ opus_int32 silk_inner_prod_aligned_scale( const opus_int len /* I vector lengths */ ); -opus_int64 silk_inner_prod16_aligned_64_c( +opus_int64 silk_inner_prod16_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ @@ -609,12 +609,14 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) /* the following seems faster on x86 */ #define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) -#if !defined(OPUS_X86_MAY_HAVE_SSE4_1) +#if !defined(OVERRIDE_silk_burg_modified) #define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) +#endif -#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ - ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len)) +#if !defined(OVERRIDE_silk_inner_prod16) +#define silk_inner_prod16(inVec1, inVec2, len, arch) \ + ((void)(arch),silk_inner_prod16_c(inVec1, inVec2, len)) #endif #include "Inlines.h" diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/VQ_WMat_EC.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/VQ_WMat_EC.c index 0f3d545c4..245a7e4b0 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/VQ_WMat_EC.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/VQ_WMat_EC.c @@ -64,7 +64,7 @@ void silk_VQ_WMat_EC_c( *rate_dist_Q8 = silk_int32_MAX; *res_nrg_Q15 = silk_int32_MAX; cb_row_Q7 = cb_Q7; - /* In things go really bad, at least *ind is set to something safe. */ + /* If things go really bad, at least *ind is set to something safe. */ *ind = 0; for( k = 0; k < L; k++ ) { opus_int32 penalty; @@ -115,7 +115,7 @@ void silk_VQ_WMat_EC_c( if( sum1_Q15 >= 0 ) { /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */ bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) ); - /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */ + /* In the following line we reduce the codelength component by half ("-1"); seems to slightly improve quality */ bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 ); if( bits_tot_Q8 <= *rate_dist_Q8 ) { *rate_dist_Q8 = bits_tot_Q8; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c index ab426bcd6..726e6667b 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c @@ -210,19 +210,23 @@ opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse predi /* Increase Q domain of the AR coefficients */ t0_s16x8 = vld1q_s16( A_Q12 + 0 ); t1_s16x8 = vld1q_s16( A_Q12 + 8 ); - t2_s16x8 = vld1q_s16( A_Q12 + 16 ); + if ( order > 16 ) { + t2_s16x8 = vld1q_s16( A_Q12 + 16 ); + } t0_s32x4 = vpaddlq_s16( t0_s16x8 ); switch( order - leftover ) { case 24: t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 ); + vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) ); + vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) ); /* FALLTHROUGH */ case 16: t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 ); - vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) ); - vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) ); + vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) ); + vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) ); /* FALLTHROUGH */ case 8: @@ -230,8 +234,8 @@ opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse predi const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) ); const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 ); DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 ); - vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) ); - vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) ); + vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) ); + vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) ); } break; @@ -246,16 +250,22 @@ opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse predi case 6: DC_resp += (opus_int32)A_Q12[ 5 ]; DC_resp += (opus_int32)A_Q12[ 4 ]; + Atmp_QA[ order - leftover + 5 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 5 ], QA - 12 ); + Atmp_QA[ order - leftover + 4 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 4 ], QA - 12 ); /* FALLTHROUGH */ case 4: DC_resp += (opus_int32)A_Q12[ 3 ]; DC_resp += (opus_int32)A_Q12[ 2 ]; + Atmp_QA[ order - leftover + 3 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 3 ], QA - 12 ); + Atmp_QA[ order - leftover + 2 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 2 ], QA - 12 ); /* FALLTHROUGH */ case 2: DC_resp += (opus_int32)A_Q12[ 1 ]; DC_resp += (opus_int32)A_Q12[ 0 ]; + Atmp_QA[ order - leftover + 1 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 1 ], QA - 12 ); + Atmp_QA[ order - leftover + 0 ] = silk_LSHIFT32( (opus_int32)A_Q12[ 0 ], QA - 12 ); /* FALLTHROUGH */ default: @@ -266,8 +276,6 @@ opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse predi if( DC_resp >= 4096 ) { invGain_Q30 = 0; } else { - vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) ); - vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) ); invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order ); } } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/bwexpander_32.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/bwexpander_32.c index d0010f73d..0f32b9df1 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/bwexpander_32.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/bwexpander_32.c @@ -31,7 +31,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "SigProc_FIX.h" -/* Chirp (bandwidth expand) LP AR filter */ +/* Chirp (bandwidth expand) LP AR filter. + This logic is reused in _celt_lpc(). Any bug fixes should also be applied there. */ void silk_bwexpander_32( opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ const opus_int d, /* I Length of ar */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/control_codec.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/control_codec.c index 52aa8fded..784ffe66d 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/control_codec.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/control_codec.c @@ -415,7 +415,7 @@ static OPUS_INLINE opus_int silk_setup_LBRR( /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */ psEncC->LBRR_GainIncreases = 7; } else { - psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); + psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.2, 16 ) ), 3 ); } } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.c index 9253faf71..46a24a47e 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.c @@ -29,19 +29,23 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +typedef int prevent_empty_translation_unit_warning; + #include "debug.h" + +#if SILK_DEBUG || SILK_TIC_TOC #include "SigProc_FIX.h" +#endif #if SILK_TIC_TOC -#ifdef _WIN32 - #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ #include #endif +#ifdef _WIN32 unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ { /* Returns a time counter in microsec */ @@ -65,7 +69,7 @@ unsigned long GetHighResolutionTime(void) /* O time in usec*/ int silk_Timer_nTimers = 0; int silk_Timer_depth_ctr = 0; char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; -#ifdef WIN32 +#ifdef _WIN32 LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; #else unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; @@ -76,7 +80,7 @@ opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; -#ifdef WIN32 +#ifdef _WIN32 void silk_TimerSave(char *file_name) { if( silk_Timer_nTimers > 0 ) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.h index 6f68c1ca0..36163e478 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/debug.h @@ -28,28 +28,29 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef SILK_DEBUG_H #define SILK_DEBUG_H -#include "typedef.h" -#include /* file writing */ -#include /* strcpy, strcmp */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -unsigned long GetHighResolutionTime(void); /* O time in usec*/ - /* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping * intermediate signals from the codec. */ #define SILK_DEBUG 0 /* Flag for using timers */ -#define SILK_TIC_TOC 0 +#define SILK_TIC_TOC 0 +#if SILK_DEBUG || SILK_TIC_TOC +#include "typedef.h" +#include /* strcpy, strcmp */ +#include /* file writing */ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif #if SILK_TIC_TOC +unsigned long GetHighResolutionTime(void); /* O time in usec*/ + #if (defined(_WIN32) || defined(_WINCE)) #include /* timer */ #else /* Linux or Mac*/ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/decode_frame.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/decode_frame.c index e73825b26..4f36f854c 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/decode_frame.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/decode_frame.c @@ -97,7 +97,6 @@ opus_int silk_decode_frame( psDec->first_frame_after_reset = 0; } else { /* Handle packet loss by extrapolation */ - psDec->indices.signalType = psDec->prevSignalType; silk_PLC( psDec, psDecCtrl, pOut, 1, arch ); } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/define.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/define.h index 247cb0bf7..491c86f33 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/define.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/define.h @@ -225,6 +225,7 @@ extern "C" /* Defines for CN generation */ #define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ #define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ +#define CNG_GAIN_SMTH_THRESHOLD_Q16 46396 /* -3 dB */ #define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ #ifdef __cplusplus diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/enc_API.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/enc_API.c index 55a33f37e..548e07364 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/enc_API.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/enc_API.c @@ -270,6 +270,7 @@ opus_int silk_Encode( /* O Returns error co psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); ALLOC( buf, nSamplesFromInputMax, opus_int16 ); while( 1 ) { + int curr_nBitsUsedLBRR = 0; nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); @@ -342,6 +343,7 @@ opus_int silk_Encode( /* O Returns error co opus_uint8 iCDF[ 2 ] = { 0, 0 }; iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); + curr_nBitsUsedLBRR = ec_tell( psRangeEnc ); /* Encode any LBRR data from previous packet */ /* Encode LBRR flags */ @@ -386,8 +388,7 @@ opus_int silk_Encode( /* O Returns error co for( n = 0; n < encControl->nChannelsInternal; n++ ) { silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); } - - psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc ); + curr_nBitsUsedLBRR = ec_tell( psRangeEnc ) - curr_nBitsUsedLBRR; } silk_HP_variable_cutoff( psEnc->state_Fxx ); @@ -396,6 +397,16 @@ opus_int silk_Encode( /* O Returns error co nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); /* Subtract bits used for LBRR */ if( !prefillFlag ) { + /* psEnc->nBitsUsedLBRR is an exponential moving average of the LBRR usage, + except that for the first LBRR frame it does no averaging and for the first + frame after after LBRR, it goes back to zero immediately. */ + if ( curr_nBitsUsedLBRR < 10 ) { + psEnc->nBitsUsedLBRR = 0; + } else if ( psEnc->nBitsUsedLBRR < 10) { + psEnc->nBitsUsedLBRR = curr_nBitsUsedLBRR; + } else { + psEnc->nBitsUsedLBRR = ( psEnc->nBitsUsedLBRR + curr_nBitsUsedLBRR ) / 2; + } nBits -= psEnc->nBitsUsedLBRR; } /* Divide by number of uncoded frames left in packet */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/LTP_scale_ctrl_FIX.c index 3dcedef89..db1016e0b 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/LTP_scale_ctrl_FIX.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/LTP_scale_ctrl_FIX.c @@ -42,9 +42,14 @@ void silk_LTP_scale_ctrl_FIX( if( condCoding == CODE_INDEPENDENTLY ) { /* Only scale if first frame in packet */ - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( - silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); + round_loss = psEnc->sCmn.PacketLoss_perc * psEnc->sCmn.nFramesPerPacket; + if ( psEnc->sCmn.LBRR_flag ) { + /* LBRR reduces the effective loss. In practice, it does not square the loss because + losses aren't independent, but that still seems to work best. We also never go below 2%. */ + round_loss = 2 + silk_SMULBB( round_loss, round_loss ) / 100; + } + psEnc->sCmn.indices.LTP_scaleIndex = silk_SMULBB( psEncCtrl->LTPredCodGain_Q7, round_loss ) > silk_log2lin( 128*7 + 2900-psEnc->sCmn.SNR_dB_Q7 ); + psEnc->sCmn.indices.LTP_scaleIndex += silk_SMULBB( psEncCtrl->LTPredCodGain_Q7, round_loss ) > silk_log2lin( 128*7 + 3900-psEnc->sCmn.SNR_dB_Q7 ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c index 00a70cb51..6f3be025c 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c @@ -84,7 +84,9 @@ void silk_warped_autocorrelation_FIX_neon( silk_assert( ( order & 1 ) == 0 ); silk_assert( 2 * QS - QC >= 0 ); - ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 ); + /* The additional +4 is to ensure a later vld1q_s32 call does not overflow. */ + /* Strictly, only +3 is needed but +4 simplifies initialization using the 4x32 neon load. */ + ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER + 4, opus_int32 ); input_QS = input_QST; /* input_QS has zero paddings in the beginning and end. */ @@ -121,6 +123,8 @@ void silk_warped_autocorrelation_FIX_neon( vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS += 4; vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); + input_QS += 4; + vst1q_s32( input_QS, vdupq_n_s32( 0 ) ); input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT; /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */ @@ -153,7 +157,8 @@ void silk_warped_autocorrelation_FIX_neon( opus_int o = orderT; int32x4_t state_QS_s32x4[ 3 ][ 2 ]; - ALLOC( state, length + orderT, opus_int32 ); + /* The additional +4 is to ensure a later vld1q_s32 call does not overflow. */ + ALLOC( state, length + order + 4, opus_int32 ); state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 ); /* Calculate 8 taps of all inputs in each loop. */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/burg_modified_FIX.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/burg_modified_FIX.c index 274d4b28e..185a12b17 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/burg_modified_FIX.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/burg_modified_FIX.c @@ -68,7 +68,7 @@ void silk_burg_modified_c( celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ - C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch ); + C0_64 = silk_inner_prod16( x, x, subfr_length*nb_subfr, arch ); lz = silk_CLZ64(C0_64); rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz; if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS; @@ -87,7 +87,7 @@ void silk_burg_modified_c( x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( - silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); + silk_inner_prod16( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); } } } else { @@ -150,7 +150,7 @@ void silk_burg_modified_c( C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ - /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32), + /* We sometimes get overflows in the multiplications (even beyond +/- 2^32), but they cancel each other and the real result seems to always fit in a 32-bit signed integer. This was determined experimentally, not theoretically (unfortunately). */ tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ @@ -253,7 +253,7 @@ void silk_burg_modified_c( if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; - C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); + C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16( x_ptr, x_ptr, D, arch ), rshifts ); } } else { for( s = 0; s < nb_subfr; s++ ) { diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/find_pred_coefs_FIX.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/find_pred_coefs_FIX.c index 606d86334..ad363fb7b 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/find_pred_coefs_FIX.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/find_pred_coefs_FIX.c @@ -42,7 +42,8 @@ void silk_find_pred_coefs_FIX( { opus_int i; opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ]; - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + /* Set to NLSF_Q15 to zero so we don't copy junk to the state. */ + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]={0}; const opus_int16 *x_ptr; opus_int16 *x_pre_ptr; VARDECL( opus_int16, LPC_in_pre ); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/vector_ops_FIX.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/vector_ops_FIX.c index d94980014..dcf84070a 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/vector_ops_FIX.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/vector_ops_FIX.c @@ -87,7 +87,7 @@ opus_int32 silk_inner_prod_aligned( #endif } -opus_int64 silk_inner_prod16_aligned_64_c( +opus_int64 silk_inner_prod16_c( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c index bbb1ce0fc..e58bf079e 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2014, Cisco Systems, INC - Written by XiangMingZhu WeiZhou MinPeng YanWang +/* Copyright (c) 2014-2020, Cisco Systems, INC + Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -42,7 +42,7 @@ #define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ #define QA 25 -#define N_BITS_HEAD_ROOM 2 +#define N_BITS_HEAD_ROOM 3 #define MIN_RSHIFTS -16 #define MAX_RSHIFTS (32 - QA) @@ -59,7 +59,7 @@ void silk_burg_modified_sse4_1( int arch /* I Run-time architecture */ ) { - opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain; + opus_int k, n, s, lz, rshifts, reached_max_gain; opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; const opus_int16 *x_ptr; opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; @@ -68,6 +68,7 @@ void silk_burg_modified_sse4_1( opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; + opus_int64 C0_64; __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210; __m128i CONST1 = _mm_set1_epi32(1); @@ -75,23 +76,18 @@ void silk_burg_modified_sse4_1( celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); /* Compute autocorrelations, added over subframes */ - silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); - if( rshifts > MAX_RSHIFTS ) { - C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); - silk_assert( C0 > 0 ); - rshifts = MAX_RSHIFTS; + C0_64 = silk_inner_prod16( x, x, subfr_length*nb_subfr, arch ); + lz = silk_CLZ64(C0_64); + rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz; + if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS; + if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS; + + if (rshifts > 0) { + C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts ); } else { - lz = silk_CLZ32( C0 ) - 1; - rshifts_extra = N_BITS_HEAD_ROOM - lz; - if( rshifts_extra > 0 ) { - rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts ); - C0 = silk_RSHIFT32( C0, rshifts_extra ); - } else { - rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts ); - C0 = silk_LSHIFT32( C0, -rshifts_extra ); - } - rshifts += rshifts_extra; + C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts ); } + CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); if( rshifts > 0 ) { @@ -99,7 +95,7 @@ void silk_burg_modified_sse4_1( x_ptr = x + s * subfr_length; for( n = 1; n < D + 1; n++ ) { C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( - silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); + silk_inner_prod16( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts ); } } } else { @@ -203,8 +199,11 @@ void silk_burg_modified_sse4_1( C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ - tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ - tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ + /* We sometimes get overflows in the multiplications (even beyond +/- 2^32), + but they cancel each other and the real result seems to always fit in a 32-bit + signed integer. This was determined experimentally, not theoretically (unfortunately). */ + tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ + tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ } tmp1 = -tmp1; /* Q17 */ @@ -350,7 +349,7 @@ void silk_burg_modified_sse4_1( if( rshifts > 0 ) { for( s = 0; s < nb_subfr; s++ ) { x_ptr = x + s * subfr_length; - C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts ); + C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16( x_ptr, x_ptr, D, arch ), rshifts ); } } else { for( s = 0; s < nb_subfr; s++ ) { @@ -374,4 +373,28 @@ void silk_burg_modified_sse4_1( *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ *res_nrg_Q = -rshifts; } + +#ifdef OPUS_CHECK_ASM + { + opus_int32 res_nrg_c = 0; + opus_int res_nrg_Q_c = 0; + opus_int32 A_Q16_c[ MAX_LPC_ORDER ] = {0}; + + silk_burg_modified_c( + &res_nrg_c, + &res_nrg_Q_c, + A_Q16_c, + x, + minInvGain_Q30, + subfr_length, + nb_subfr, + D, + 0 + ); + + silk_assert( *res_nrg == res_nrg_c ); + silk_assert( *res_nrg_Q == res_nrg_Q_c ); + silk_assert( !memcmp( A_Q16, A_Q16_c, D * sizeof( *A_Q16 ) ) ); + } +#endif } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c index c1e90564d..a46289bbc 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c @@ -36,40 +36,38 @@ #include "SigProc_FIX.h" #include "pitch.h" +#include "celt/x86/x86cpu.h" -opus_int64 silk_inner_prod16_aligned_64_sse4_1( +opus_int64 silk_inner_prod16_sse4_1( const opus_int16 *inVec1, /* I input vector 1 */ const opus_int16 *inVec2, /* I input vector 2 */ const opus_int len /* I vector lengths */ ) { - opus_int i, dataSize8; + opus_int i, dataSize4; opus_int64 sum; - __m128i xmm_tempa; - __m128i inVec1_76543210, acc1; - __m128i inVec2_76543210, acc2; + __m128i xmm_prod_20, xmm_prod_31; + __m128i inVec1_3210, acc1; + __m128i inVec2_3210, acc2; sum = 0; - dataSize8 = len & ~7; + dataSize4 = len & ~3; acc1 = _mm_setzero_si128(); acc2 = _mm_setzero_si128(); - for( i = 0; i < dataSize8; i += 8 ) { - inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) ); - inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) ); + for( i = 0; i < dataSize4; i += 4 ) { + inVec1_3210 = OP_CVTEPI16_EPI32_M64( &inVec1[i + 0] ); + inVec2_3210 = OP_CVTEPI16_EPI32_M64( &inVec2[i + 0] ); + xmm_prod_20 = _mm_mul_epi32( inVec1_3210, inVec2_3210 ); - /* only when all 4 operands are -32768 (0x8000), this results in wrap around */ - inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 ); + inVec1_3210 = _mm_shuffle_epi32( inVec1_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) ); + inVec2_3210 = _mm_shuffle_epi32( inVec2_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) ); + xmm_prod_31 = _mm_mul_epi32( inVec1_3210, inVec2_3210 ); - xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 ); - /* equal shift right 8 bytes */ - inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) ); - inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 ); - - acc1 = _mm_add_epi64( acc1, xmm_tempa ); - acc2 = _mm_add_epi64( acc2, inVec1_76543210 ); + acc1 = _mm_add_epi64( acc1, xmm_prod_20 ); + acc2 = _mm_add_epi64( acc2, xmm_prod_31 ); } acc1 = _mm_add_epi64( acc1, acc2 ); @@ -81,8 +79,15 @@ opus_int64 silk_inner_prod16_aligned_64_sse4_1( _mm_storel_epi64( (__m128i *)&sum, acc1 ); for( ; i < len; i++ ) { - sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); + sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); + } + +#ifdef OPUS_CHECK_ASM + { + opus_int64 sum_c = silk_inner_prod16_c( inVec1, inVec2, len ); + silk_assert( sum == sum_c ); } +#endif return sum; } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/LTP_scale_ctrl_FLP.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/LTP_scale_ctrl_FLP.c index 8dbe29d0f..6f30ff095 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/LTP_scale_ctrl_FLP.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/LTP_scale_ctrl_FLP.c @@ -41,8 +41,14 @@ void silk_LTP_scale_ctrl_FLP( if( condCoding == CODE_INDEPENDENTLY ) { /* Only scale if first frame in packet */ - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f ); + round_loss = psEnc->sCmn.PacketLoss_perc * psEnc->sCmn.nFramesPerPacket; + if ( psEnc->sCmn.LBRR_flag ) { + /* LBRR reduces the effective loss. In practice, it does not square the loss because + losses aren't independent, but that still seems to work best. We also never go below 2%. */ + round_loss = 2 + silk_SMULBB( round_loss, round_loss) / 100; + } + psEnc->sCmn.indices.LTP_scaleIndex = silk_SMULBB( psEncCtrl->LTPredCodGain, round_loss ) > silk_log2lin( 2900 - psEnc->sCmn.SNR_dB_Q7 ); + psEnc->sCmn.indices.LTP_scaleIndex += silk_SMULBB( psEncCtrl->LTPredCodGain, round_loss ) > silk_log2lin( 3900 - psEnc->sCmn.SNR_dB_Q7 ); } else { /* Default is minimum scaling */ psEnc->sCmn.indices.LTP_scaleIndex = 0; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/find_pred_coefs_FLP.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/find_pred_coefs_FLP.c index dcf7c5202..6f7907889 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/find_pred_coefs_FLP.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/find_pred_coefs_FLP.c @@ -44,7 +44,8 @@ void silk_find_pred_coefs_FLP( silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ]; silk_float invGains[ MAX_NB_SUBFR ]; - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + /* Set to NLSF_Q15 to zero so we don't copy junk to the state. */ + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]={0}; const silk_float *x_ptr; silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; silk_float minInvGain; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/wrappers_FLP.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/wrappers_FLP.c index ad90b874a..c0c183e35 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/float/wrappers_FLP.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/float/wrappers_FLP.c @@ -190,12 +190,14 @@ void silk_quant_LTP_gains_FLP( opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ]; - for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { + i = 0; + do { XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f ); - } - for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { + } while ( ++i < nb_subfr * LTP_ORDER * LTP_ORDER ); + i = 0; + do { xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f ); - } + } while ( ++i < nb_subfr * LTP_ORDER ); silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch ); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/main.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/main.h index 1a33eed54..a5f568758 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/main.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/main.h @@ -247,21 +247,21 @@ void silk_VQ_WMat_EC_c( /************************************/ void silk_NSQ_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ) @@ -273,21 +273,21 @@ void silk_NSQ_c( /* Noise shaping using delayed decision */ void silk_NSQ_del_dec_c( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int16 x16[], /* I Input */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); #if !defined(OVERRIDE_silk_NSQ_del_dec) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/meson.build b/libfenrir/src/main/jni/audio/opus/libopus/silk/meson.build new file mode 100644 index 000000000..917048b2d --- /dev/null +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/meson.build @@ -0,0 +1,63 @@ +silk_sources = sources['SILK_SOURCES'] + +silk_sources_sse4_1 = sources['SILK_SOURCES_SSE4_1'] + +silk_sources_neon_intr = sources['SILK_SOURCES_ARM_NEON_INTR'] + +silk_sources_fixed_neon_intr = sources['SILK_SOURCES_FIXED_ARM_NEON_INTR'] + +silk_sources_fixed = sources['SILK_SOURCES_FIXED'] + +silk_sources_fixed_sse4_1 = sources['SILK_SOURCES_FIXED_SSE4_1'] + +silk_sources_float = sources['SILK_SOURCES_FLOAT'] + +if opt_fixed_point + silk_sources += silk_sources_fixed +else + silk_sources += silk_sources_float +endif + +silk_includes = [opus_includes, include_directories('float', 'fixed')] +silk_static_libs = [] + +if host_cpu_family in ['x86', 'x86_64'] and opus_conf.has('OPUS_HAVE_RTCD') + silk_sources += sources['SILK_SOURCES_X86_RTCD'] +endif + +if host_cpu_family in ['arm', 'aarch64'] and have_arm_intrinsics_or_asm + if opus_conf.has('OPUS_HAVE_RTCD') + silk_sources += sources['SILK_SOURCES_ARM_RTCD'] + endif +endif + +foreach intr_name : ['sse4_1', 'neon_intr'] + have_intr = get_variable('have_' + intr_name) + if not have_intr + continue + endif + + intr_sources = get_variable('silk_sources_' + intr_name) + if opt_fixed_point + intr_sources += get_variable('silk_sources_fixed_' + intr_name) + endif + + intr_args = get_variable('opus_@0@_args'.format(intr_name), []) + silk_static_libs += static_library('silk_' + intr_name, intr_sources, + c_args: intr_args, + include_directories: silk_includes, + install: false) +endforeach + +silk_c_args = [] +if host_machine.system() == 'windows' + silk_c_args += ['-DDLL_EXPORT'] +endif + +silk_lib = static_library('opus-silk', + silk_sources, + c_args: silk_c_args, + include_directories: silk_includes, + link_whole: silk_static_libs, + dependencies: libm, + install: false) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/NSQ_del_dec_mipsr1.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/NSQ_del_dec_mipsr1.h deleted file mode 100644 index cd70713a8..000000000 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/NSQ_del_dec_mipsr1.h +++ /dev/null @@ -1,410 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef __NSQ_DEL_DEC_MIPSR1_H__ -#define __NSQ_DEL_DEC_MIPSR1_H__ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "stack_alloc.h" - -#define OVERRIDE_silk_noise_shape_quantizer_del_dec -static inline void silk_noise_shape_quantizer_del_dec( - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP filter state */ - opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int subfr, /* I Subframe number */ - opus_int shapingLPCOrder, /* I Shaping LPC filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - opus_int warping_Q16, /* I */ - opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ - opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */ - opus_int decisionDelay, /* I */ - int arch /* I */ -) -{ - opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; - opus_int32 Winner_rand_state; - opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; - opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; - opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; - opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; - opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; - NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; - NSQ_del_dec_struct *psDD; - NSQ_sample_struct *psSS; - opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4; - opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6; - opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13; - opus_int16 a_Q12_14, a_Q12_15; - - opus_int32 cur, prev, next; - - /*Unused.*/ - (void)arch; - - //Intialize b_Q14 variables - b_Q14_0 = b_Q14[ 0 ]; - b_Q14_1 = b_Q14[ 1 ]; - b_Q14_2 = b_Q14[ 2 ]; - b_Q14_3 = b_Q14[ 3 ]; - b_Q14_4 = b_Q14[ 4 ]; - - //Intialize a_Q12 variables - a_Q12_0 = a_Q12[0]; - a_Q12_1 = a_Q12[1]; - a_Q12_2 = a_Q12[2]; - a_Q12_3 = a_Q12[3]; - a_Q12_4 = a_Q12[4]; - a_Q12_5 = a_Q12[5]; - a_Q12_6 = a_Q12[6]; - a_Q12_7 = a_Q12[7]; - a_Q12_8 = a_Q12[8]; - a_Q12_9 = a_Q12[9]; - a_Q12_10 = a_Q12[10]; - a_Q12_11 = a_Q12[11]; - a_Q12_12 = a_Q12[12]; - a_Q12_13 = a_Q12[13]; - a_Q12_14 = a_Q12[14]; - a_Q12_15 = a_Q12[15]; - - long long temp64; - - silk_assert( nStatesDelayedDecision > 0 ); - - shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; - pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); - - for( i = 0; i < length; i++ ) { - /* Perform common calculations used in all states */ - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 ); - temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 ); - temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 ); - temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 ); - temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 ); - temp64 += 32768; - LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16); - LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ - pred_lag_ptr++; - } else { - LTP_pred_Q14 = 0; - } - - /* Long-term shaping */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ - shp_lag_ptr++; - } else { - n_LTP_Q14 = 0; - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - /* Delayed decision state */ - psDD = &psDelDec[ k ]; - - /* Sample state */ - psSS = psSampleState[ k ]; - - /* Generate dither */ - psDD->Seed = silk_RAND( psDD->Seed ); - - /* Pointer used in short term prediction and shaping */ - psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; - /* Short-term prediction */ - silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); - temp64 = __builtin_mips_mult(psLPC_Q14[ 0 ], a_Q12_0 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 ); - if( predictLPCOrder == 16 ) { - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 ); - temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 ); - } - temp64 += 32768; - LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16); - - LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ - - /* Noise shape feedback */ - silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ - /* Output of lowpass section */ - tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ 0 ] = tmp2; - - temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] ); - - prev = psDD->sAR2_Q14[ 1 ]; - - /* Loop over allpass sections */ - for( j = 2; j < shapingLPCOrder; j += 2 ) { - cur = psDD->sAR2_Q14[ j ]; - next = psDD->sAR2_Q14[ j+1 ]; - /* Output of allpass section */ - tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 ); - psDD->sAR2_Q14[ j - 1 ] = tmp1; - temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] ); - temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ j + 0 ] = tmp2; - prev = next; - } - psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; - temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); - temp64 += 32768; - n_AR_Q14 = __builtin_mips_extr_w(temp64, 16); - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ - - n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ - - /* Input minus prediction plus noise feedback */ - /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ - tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ - tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ - tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ - - r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - if ( psDD->Seed < 0 ) { - r_Q10 = -r_Q10; - } - r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); - q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); - if( q1_Q0 > 0 ) { - q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == 0 ) { - q1_Q10 = offset_Q10; - q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == -1 ) { - q2_Q10 = offset_Q10; - q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else { /* q1_Q0 < -1 */ - q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); - } - rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); - rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); - rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); - rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); - - if( rd1_Q10 < rd2_Q10 ) { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 0 ].Q_Q10 = q1_Q10; - psSS[ 1 ].Q_Q10 = q2_Q10; - } else { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 0 ].Q_Q10 = q2_Q10; - psSS[ 1 ].Q_Q10 = q1_Q10; - } - - /* Update states for best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 0 ].xq_Q14 = xq_Q14; - - /* Update states for second best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 1 ].xq_Q14 = xq_Q14; - } - - *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY; - if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY; - last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY; - - /* Find winner */ - RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - Winner_ind = k; - } - } - - /* Increase RD values of expired states */ - Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; - for( k = 0; k < nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { - psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); - psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); - silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); - } - } - - /* Find worst in first set and best in second set */ - RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; - RDmax_ind = 0; - RDmin_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - /* find worst in first set */ - if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { - RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - RDmax_ind = k; - } - /* find best in second set */ - if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; - RDmin_ind = k; - } - } - - /* Replace a state if best from second set outperforms worst in first set */ - if( RDmin_Q10 < RDmax_Q10 ) { - silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, - ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); - silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); - } - - /* Write samples from winner to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - if( subfr > 0 || i >= decisionDelay ) { - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; - sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; - } - NSQ->sLTP_shp_buf_idx++; - NSQ->sLTP_buf_idx++; - - /* Update states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - psSS = &psSampleState[ k ][ 0 ]; - psDD->LF_AR_Q14 = psSS->LF_AR_Q14; - psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; - psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; - psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; - psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); - psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; - psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); - psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; - psDD->RD_Q10 = psSS->RD_Q10; - } - delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; - } - /* Update LPC states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - } -} - -#endif /* __NSQ_DEL_DEC_MIPSR1_H__ */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/macros_mipsr1.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/macros_mipsr1.h deleted file mode 100644 index 12ed981a6..000000000 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/macros_mipsr1.h +++ /dev/null @@ -1,92 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - - -#ifndef __SILK_MACROS_MIPSR1_H__ -#define __SILK_MACROS_MIPSR1_H__ - -#define mips_clz(x) __builtin_clz(x) - -#undef silk_SMULWB -static inline int silk_SMULWB(int a, int b) -{ - long long ac; - int c; - - ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b); - c = __builtin_mips_extr_w(ac, 16); - - return c; -} - -#undef silk_SMLAWB -#define silk_SMLAWB(a32, b32, c32) ((a32) + silk_SMULWB(b32, c32)) - -#undef silk_SMULWW -static inline int silk_SMULWW(int a, int b) -{ - long long ac; - int c; - - ac = __builtin_mips_mult(a, b); - c = __builtin_mips_extr_w(ac, 16); - - return c; -} - -#undef silk_SMLAWW -static inline int silk_SMLAWW(int a, int b, int c) -{ - long long ac; - int res; - - ac = __builtin_mips_mult(b, c); - res = __builtin_mips_extr_w(ac, 16); - res += a; - - return res; -} - -#define OVERRIDE_silk_CLZ16 -static inline opus_int32 silk_CLZ16(opus_int16 in16) -{ - int re32; - opus_int32 in32 = (opus_int32 )in16; - re32 = mips_clz(in32); - re32-=16; - return re32; -} - -#define OVERRIDE_silk_CLZ32 -static inline opus_int32 silk_CLZ32(opus_int32 in32) -{ - int re32; - re32 = mips_clz(in32); - return re32; -} - -#endif /* __SILK_MACROS_MIPSR1_H__ */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/sigproc_fix_mipsr1.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/sigproc_fix_mipsr1.h deleted file mode 100644 index 51520c0a6..000000000 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/mips/sigproc_fix_mipsr1.h +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_SIGPROC_FIX_MIPSR1_H -#define SILK_SIGPROC_FIX_MIPSR1_H - -#undef silk_SAT16 -static inline short int silk_SAT16(int a) -{ - int c; - c = __builtin_mips_shll_s_w(a, 16); - c = c>>16; - - return c; -} - -#undef silk_LSHIFT_SAT32 -static inline int silk_LSHIFT_SAT32(int a, int shift) -{ - int r; - - r = __builtin_mips_shll_s_w(a, shift); - - return r; -} - -#undef silk_RSHIFT_ROUND -static inline int silk_RSHIFT_ROUND(int a, int shift) -{ - int r; - - r = __builtin_mips_shra_r_w(a, shift); - return r; -} - -#endif /* SILK_SIGPROC_FIX_MIPSR1_H */ diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_LR_to_MS.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_LR_to_MS.c index c8226663c..751452cb1 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_LR_to_MS.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_LR_to_MS.c @@ -77,7 +77,7 @@ void silk_stereo_LR_to_MS( ALLOC( LP_mid, frame_length, opus_int16 ); ALLOC( HP_mid, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); LP_mid[ n ] = sum; HP_mid[ n ] = mid[ n + 1 ] - sum; } @@ -86,7 +86,7 @@ void silk_stereo_LR_to_MS( ALLOC( LP_side, frame_length, opus_int16 ); ALLOC( HP_side, frame_length, opus_int16 ); for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT32( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); LP_side[ n ] = sum; HP_side[ n ] = side[ n + 1 ] - sum; } @@ -207,7 +207,7 @@ void silk_stereo_LR_to_MS( pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; w_Q24 += deltaw_Q24; - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); @@ -217,7 +217,7 @@ void silk_stereo_LR_to_MS( pred1_Q13 = -pred_Q13[ 1 ]; w_Q24 = silk_LSHIFT( width_Q14, 10 ); for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_MS_to_LR.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_MS_to_LR.c index 62521a4f3..1e01bb6eb 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_MS_to_LR.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/stereo_MS_to_LR.c @@ -59,7 +59,7 @@ void silk_stereo_MS_to_LR( for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { pred0_Q13 += delta0_Q13; pred1_Q13 += delta1_Q13; - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( x1[ n ] + (opus_int32)x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); @@ -67,7 +67,7 @@ void silk_stereo_MS_to_LR( pred0_Q13 = pred_Q13[ 0 ]; pred1_Q13 = pred_Q13[ 1 ]; for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_LSHIFT( silk_ADD_LSHIFT32( x1[ n ] + (opus_int32)x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c deleted file mode 100644 index 67067cead..000000000 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c +++ /dev/null @@ -1,129 +0,0 @@ -/*********************************************************************** -Copyright (c) 2017 Google Inc., Jean-Marc Valin -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include "celt/stack_alloc.h" -#include "cpu_support.h" -#include "SigProc_FIX.h" - -/* Computes the impulse response of the filter so we - can catch filters that are definitely unstable. Some - unstable filters may be classified as stable, but not - the other way around. */ -int check_stability(opus_int16 *A_Q12, int order) { - int i; - int j; - int sum_a, sum_abs_a; - sum_a = sum_abs_a = 0; - for( j = 0; j < order; j++ ) { - sum_a += A_Q12[ j ]; - sum_abs_a += silk_abs( A_Q12[ j ] ); - } - /* Check DC stability. */ - if( sum_a >= 4096 ) { - return 0; - } - /* If the sum of absolute values is less than 1, the filter - has to be stable. */ - if( sum_abs_a < 4096 ) { - return 1; - } - double y[SILK_MAX_ORDER_LPC] = {0}; - y[0] = 1; - for( i = 0; i < 10000; i++ ) { - double sum = 0; - for( j = 0; j < order; j++ ) { - sum += y[ j ]*A_Q12[ j ]; - } - for( j = order - 1; j > 0; j-- ) { - y[ j ] = y[ j - 1 ]; - } - y[ 0 ] = sum*(1./4096); - /* If impulse response reaches +/- 10000, the filter - is definitely unstable. */ - if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) { - return 0; - } - /* Test every 8 sample for low amplitude. */ - if( ( i & 0x7 ) == 0 ) { - double amp = 0; - for( j = 0; j < order; j++ ) { - amp += fabs(y[j]); - } - if( amp < 0.00001 ) { - return 1; - } - } - } - return 1; -} - -int main(void) { - const int arch = opus_select_arch(); - /* Set to 10000 so all branches in C function are triggered */ - const int loop_num = 10000; - int count = 0; - ALLOC_STACK; - - /* FIXME: Make the seed random (with option to set it explicitly) - so we get wider coverage. */ - srand(0); - - printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n"); - for( count = 0; count < loop_num; count++ ) { - unsigned int i; - opus_int order; - unsigned int shift; - opus_int16 A_Q12[ SILK_MAX_ORDER_LPC ]; - opus_int32 gain; - - for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */ - for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */ - for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) { - A_Q12[i] = ((opus_int16)rand()) >> shift; - } - gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch); - /* Look for filters that silk_LPC_inverse_pred_gain() thinks are - stable but definitely aren't. */ - if( gain != 0 && !check_stability(A_Q12, order) ) { - fprintf(stderr, "**Loop %4d failed!**\n", count); - return 1; - } - } - } - if( !(count % 500) ) { - printf("Loop %4d passed\n", count); - } - } - printf("silk_LPC_inverse_pred_gain() optimization passed\n"); - return 0; -} diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/typedef.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/typedef.h index 97b7e709b..793d2c0c1 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/typedef.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/typedef.h @@ -67,6 +67,9 @@ __attribute__((noreturn)) static OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line) { fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); +#if defined(_MSC_VER) + _set_abort_behavior( 0, _WRITE_ABORT_MSG); +#endif abort(); } # define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}} diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_del_dec_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_del_dec_sse4_1.c index 2c75ede2d..a58a76cd8 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_del_dec_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_del_dec_sse4_1.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2014, Cisco Systems, INC - Written by XiangMingZhu WeiZhou MinPeng YanWang +/* Copyright (c) 2014-2020, Cisco Systems, INC + Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -46,6 +46,7 @@ typedef struct { opus_int32 Shape_Q14[ DECISION_DELAY ]; opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_AR_Q14; + opus_int32 Diff_Q14; opus_int32 Seed; opus_int32 SeedInit; opus_int32 RD_Q10; @@ -56,6 +57,7 @@ typedef struct { opus_int32 RD_Q10; opus_int32 xq_Q14; opus_int32 LF_AR_Q14; + opus_int32 Diff_Q14; opus_int32 sLTP_shp_Q14; opus_int32 LPC_exc_Q14; } NSQ_sample_struct; @@ -66,7 +68,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int32 x_Q3[], /* I Input in Q3 */ + const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ @@ -112,21 +114,21 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( ); void silk_NSQ_del_dec_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; @@ -142,8 +144,39 @@ void silk_NSQ_del_dec_sse4_1( VARDECL( opus_int32, delayedGain_Q10 ); VARDECL( NSQ_del_dec_struct, psDelDec ); NSQ_del_dec_struct *psDD; +#ifdef OPUS_CHECK_ASM + silk_nsq_state NSQ_c; + SideInfoIndices psIndices_c; + opus_int8 pulses_c[ MAX_FRAME_LENGTH ]; + const opus_int8 *const pulses_a = pulses; +#endif SAVE_STACK; +#ifdef OPUS_CHECK_ASM + ( void )pulses_a; + silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) ); + silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) ); + silk_assert( psEncC->nb_subfr * psEncC->subfr_length <= MAX_FRAME_LENGTH ); + silk_memcpy( pulses_c, pulses, psEncC->nb_subfr * psEncC->subfr_length * sizeof( pulses[0] ) ); + silk_NSQ_del_dec_c( + psEncC, + &NSQ_c, + &psIndices_c, + x16, + pulses_c, + PredCoef_Q12, + LTPCoef_Q14, + AR_Q13, + HarmShapeGain_Q14, + Tilt_Q14, + LF_shp_Q14, + Gains_Q16, + pitchL, + Lambda_Q10, + LTP_scale_Q14 + ); +#endif + /* Set unvoiced lag to the previous one, overwrite later for voiced */ lag = NSQ->lagPrev; @@ -158,6 +191,7 @@ void silk_NSQ_del_dec_sse4_1( psDD->SeedInit = psDD->Seed; psDD->RD_Q10 = 0; psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; + psDD->Diff_Q14 = NSQ->sDiff_shp_Q14; psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); @@ -185,8 +219,7 @@ void silk_NSQ_del_dec_sse4_1( LSF_interpolation_flag = 1; } - ALLOC( sLTP_Q15, - psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); @@ -198,7 +231,7 @@ void silk_NSQ_del_dec_sse4_1( for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); @@ -257,7 +290,7 @@ void silk_NSQ_del_dec_sse4_1( } } - silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, + silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k, psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, @@ -265,7 +298,7 @@ void silk_NSQ_del_dec_sse4_1( Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); - x_Q3 += psEncC->subfr_length; + x16 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } @@ -288,6 +321,7 @@ void silk_NSQ_del_dec_sse4_1( for( i = 0; i < decisionDelay; i++ ) { last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY; if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY; + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); @@ -298,11 +332,19 @@ void silk_NSQ_del_dec_sse4_1( /* Update states */ NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; + NSQ->sDiff_shp_Q14 = psDD->Diff_Q14; NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; /* Save quantized speech signal */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + +#ifdef OPUS_CHECK_ASM + silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) ); + silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) ); + silk_assert( !memcmp( pulses_c, pulses_a, psEncC->nb_subfr * psEncC->subfr_length * sizeof( pulses[0] ) ) ); +#endif + RESTORE_STACK; } @@ -345,6 +387,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; + int rdo_offset; + VARDECL( NSQ_sample_pair, psSampleState ); NSQ_del_dec_struct *psDD; NSQ_sample_struct *psSS; @@ -356,6 +400,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( celt_assert( nStatesDelayedDecision > 0 ); ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); + rdo_offset = (Lambda_Q10 >> 1) - 512; + shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); @@ -407,8 +453,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( /* Long-term shaping */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SMULWB( silk_ADD_SAT32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ shp_lag_ptr++; } else { @@ -478,7 +524,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 ); tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp ); - /* setp 4 */ + /* step 4 */ psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) ); psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF ); @@ -511,9 +557,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ /* Noise shape feedback */ - silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ + celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ /* Output of lowpass section */ - tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); + tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 ); /* Output of allpass section */ tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); psDD->sAR2_Q14[ 0 ] = tmp2; @@ -543,9 +589,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( /* Input minus prediction plus noise feedback */ /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ + tmp1 = silk_ADD_SAT32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ - tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ + tmp1 = silk_SUB_SAT32( tmp2, tmp1 ); /* Q13 */ tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ @@ -559,6 +605,18 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); + if (Lambda_Q10 > 2048) { + /* For aggressive RDO, the bias becomes more than one pulse. */ + if (q1_Q10 > rdo_offset) { + q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); + } else if (q1_Q10 < -rdo_offset) { + q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); + } else if (q1_Q10 < 0) { + q1_Q0 = -1; + } else { + q1_Q0 = 0; + } + } if( q1_Q0 > 0 ) { q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); @@ -612,8 +670,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); + sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 ); + psSS[ 0 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 0 ].xq_Q14 = xq_Q14; @@ -626,14 +685,14 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( exc_Q14 = -exc_Q14; } - /* Add predictions */ LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 ); + sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 ); + psSS[ 1 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 ); psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; psSS[ 1 ].xq_Q14 = xq_Q14; @@ -705,6 +764,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1( psDD = &psDelDec[ k ]; psSS = &psSampleState[ k ][ 0 ]; psDD->LF_AR_Q14 = psSS->LF_AR_Q14; + psDD->Diff_Q14 = psSS->Diff_Q14; psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; @@ -728,7 +788,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( const silk_encoder_state *psEncC, /* I Encoder State */ silk_nsq_state *NSQ, /* I/O NSQ state */ NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int32 x_Q3[], /* I Input in Q3 */ + const opus_int16 x16[], /* I Input */ opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ @@ -742,51 +802,41 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( ) { opus_int i, k, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; + opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; NSQ_del_dec_struct *psDD; - __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; + __m128i xmm_inv_gain_Q26, xmm_x16_x2x0, xmm_x16_x3x1; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); - silk_assert( inv_gain_Q31 != 0 ); - /* Calculate gain adjustment factor */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - } else { - gain_adj_Q16 = (opus_int32)1 << 16; - } - /* Scale input */ - inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); + inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); - /* prepare inv_gain_Q23 in packed 4 32-bits */ - xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); + /* prepare inv_gain_Q26 in packed 4 32-bits */ + xmm_inv_gain_Q26 = _mm_set1_epi32(inv_gain_Q26); for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { - xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); + xmm_x16_x2x0 = OP_CVTEPI16_EPI32_M64( &(x16[ i ] ) ); + /* equal shift right 4 bytes*/ - xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); + xmm_x16_x3x1 = _mm_shuffle_epi32( xmm_x16_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); - xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); - xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); + xmm_x16_x2x0 = _mm_mul_epi32( xmm_x16_x2x0, xmm_inv_gain_Q26 ); + xmm_x16_x3x1 = _mm_mul_epi32( xmm_x16_x3x1, xmm_inv_gain_Q26 ); - xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); - xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); + xmm_x16_x2x0 = _mm_srli_epi64( xmm_x16_x2x0, 16 ); + xmm_x16_x3x1 = _mm_slli_epi64( xmm_x16_x3x1, 16 ); - xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); + xmm_x16_x2x0 = _mm_blend_epi16( xmm_x16_x2x0, xmm_x16_x3x1, 0xCC ); - _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 ); + _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x16_x2x0 ); } for( ; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); + x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); } - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { @@ -800,7 +850,9 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( } /* Adjust for changing gain */ - if( gain_adj_Q16 != (opus_int32)1 << 16 ) { + if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { + gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); + /* Scale long-term shaping state */ { __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; @@ -841,6 +893,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( /* Scale scalar states */ psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); + psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { @@ -855,5 +908,8 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1( } } } + + /* Save inverse gain */ + NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; } } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_sse4_1.c index b0315e35f..d5ae1d3b1 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/NSQ_sse4_1.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2014, Cisco Systems, INC - Written by XiangMingZhu WeiZhou MinPeng YanWang +/* Copyright (c) 2014-2020, Cisco Systems, INC + Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -37,17 +37,17 @@ #include "stack_alloc.h" static OPUS_INLINE void silk_nsq_scale_states_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int32 x_Q3[], /* I input in Q3 */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + const opus_int16 x16[], /* I input */ + opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ + const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I subframe number */ + const opus_int LTP_scale_Q14, /* I */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type /* I Signal type */ ); static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( @@ -65,27 +65,28 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int32 table[][4] /* I */ ); void silk_NSQ_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) { opus_int k, lag, start_idx, LSF_interpolation_flag; @@ -101,8 +102,41 @@ void silk_NSQ_sse4_1( opus_int32 tmp1; opus_int32 q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; +#ifdef OPUS_CHECK_ASM + silk_nsq_state NSQ_c; + SideInfoIndices psIndices_c; + opus_int8 pulses_c[ MAX_FRAME_LENGTH ]; + const opus_int8 *const pulses_a = pulses; +#endif + SAVE_STACK; +#ifdef OPUS_CHECK_ASM + ( void )pulses_a; + silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) ); + silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) ); + silk_assert( psEncC->nb_subfr * psEncC->subfr_length <= MAX_FRAME_LENGTH ); + silk_memcpy( pulses_c, pulses, psEncC->nb_subfr * psEncC->subfr_length * sizeof( pulses[0] ) ); + + silk_NSQ_c( + psEncC, + &NSQ_c, + &psIndices_c, + x16, + pulses_c, + PredCoef_Q12, + LTPCoef_Q14, + AR_Q13, + HarmShapeGain_Q14, + Tilt_Q14, + LF_shp_Q14, + Gains_Q16, + pitchL, + Lambda_Q10, + LTP_scale_Q14 + ); +#endif + NSQ->rand_seed = psIndices->Seed; /* Set unvoiced lag to the previous one, overwrite later for voiced */ @@ -172,8 +206,7 @@ void silk_NSQ_sse4_1( LSF_interpolation_flag = 1; } - ALLOC( sLTP_Q15, - psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); /* Set up pointers to start of sub frame */ @@ -183,7 +216,7 @@ void silk_NSQ_sse4_1( for( k = 0; k < psEncC->nb_subfr; k++ ) { A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ]; /* Noise shape parameters */ silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); @@ -209,12 +242,12 @@ void silk_NSQ_sse4_1( } } - silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); + silk_nsq_scale_states_sse4_1( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) ) { silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, - AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], + AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, &(table[32]) ); } else @@ -224,7 +257,7 @@ void silk_NSQ_sse4_1( offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch ); } - x_Q3 += psEncC->subfr_length; + x16 += psEncC->subfr_length; pulses += psEncC->subfr_length; pxq += psEncC->subfr_length; } @@ -235,12 +268,19 @@ void silk_NSQ_sse4_1( /* Save quantized speech and noise shaping signals */ silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + +#ifdef OPUS_CHECK_ASM + silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) ); + silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) ); + silk_assert( !memcmp( pulses_c, pulses_a, psEncC->nb_subfr * psEncC->subfr_length * sizeof( pulses[0] ) ) ); +#endif + RESTORE_STACK; } -/***********************************/ -/* silk_noise_shape_quantizer_10_16 */ -/***********************************/ +/************************************/ +/* silk_noise_shape_quantizer_10_16 */ +/************************************/ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( silk_nsq_state *NSQ, /* I/O NSQ state */ opus_int signalType, /* I Signal type */ @@ -256,6 +296,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( opus_int Tilt_Q14, /* I Spectral tilt */ opus_int32 LF_shp_Q14, /* I */ opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ opus_int offset_Q10, /* I */ opus_int length, /* I Input length */ opus_int32 table[][4] /* I */ @@ -264,7 +305,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( opus_int i; opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; opus_int32 n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10; - opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; + opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10, sDiff_shp_Q14; opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; @@ -279,6 +320,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210; __m128i AR_shp_Q13_76543210; + int rdo_offset = (Lambda_Q10 >> 1) - 512; + shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); @@ -288,6 +331,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14; xq_Q14 = psLPC_Q14[ 0 ]; + sDiff_shp_Q14 = NSQ->sDiff_shp_Q14; LTP_pred_Q13 = 0; /* load a_Q12 */ @@ -430,8 +474,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 ); sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 ); - sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 ); - sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14), 0 ); + sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (sDiff_shp_Q14 >> 16), 0 ); + sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (sDiff_shp_Q14), 0 ); /* high part, use pmaddwd, results in 4 32-bit */ xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 ); @@ -462,14 +506,14 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 ); - silk_assert( lag > 0 || signalType != TYPE_VOICED ); + celt_assert( lag > 0 || signalType != TYPE_VOICED ); /* Combine prediction and noise shaping signals */ tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ if( lag > 0 ) { /* Symmetric, packed FIR coefficients */ - n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q13 = silk_SMULWB( silk_ADD_SAT32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); shp_lag_ptr++; @@ -495,6 +539,18 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( /* Find two quantization level candidates and measure their rate-distortion */ q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); + if (Lambda_Q10 > 2048) { + /* For aggressive RDO, the bias becomes more than one pulse. */ + if (q1_Q10 > rdo_offset) { + q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 ); + } else if (q1_Q10 < -rdo_offset) { + q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 ); + } else if (q1_Q10 < 0) { + q1_Q0 = -1; + } else { + q1_Q0 = 0; + } + } q1_Q10 = table[q1_Q0][0]; q2_Q10 = table[q1_Q0][1]; @@ -519,7 +575,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( /* Update states */ psLPC_Q14++; *psLPC_Q14 = xq_Q14; - sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 ); + NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 ); + sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 ); NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); @@ -600,64 +657,54 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1( } static OPUS_INLINE void silk_nsq_scale_states_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int32 x_Q3[], /* I input in Q3 */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + const opus_int16 x16[], /* I input */ + opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ + const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I subframe number */ + const opus_int LTP_scale_Q14, /* I */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type /* I Signal type */ ) { opus_int i, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; - __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1; + opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26; + __m128i xmm_inv_gain_Q26, xmm_x16_x2x0, xmm_x16_x3x1; lag = pitchL[ subfr ]; inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); silk_assert( inv_gain_Q31 != 0 ); - /* Calculate gain adjustment factor */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - } else { - gain_adj_Q16 = (opus_int32)1 << 16; - } - /* Scale input */ - inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); + inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 ); - /* prepare inv_gain_Q23 in packed 4 32-bits */ - xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23); + /* prepare inv_gain_Q26 in packed 4 32-bits */ + xmm_inv_gain_Q26 = _mm_set1_epi32(inv_gain_Q26); for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) { - xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) ); + xmm_x16_x2x0 = OP_CVTEPI16_EPI32_M64( &(x16[ i ] ) ); /* equal shift right 4 bytes*/ - xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); + xmm_x16_x3x1 = _mm_shuffle_epi32( xmm_x16_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) ); - xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 ); - xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 ); + xmm_x16_x2x0 = _mm_mul_epi32( xmm_x16_x2x0, xmm_inv_gain_Q26 ); + xmm_x16_x3x1 = _mm_mul_epi32( xmm_x16_x3x1, xmm_inv_gain_Q26 ); - xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 ); - xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 ); + xmm_x16_x2x0 = _mm_srli_epi64( xmm_x16_x2x0, 16 ); + xmm_x16_x3x1 = _mm_slli_epi64( xmm_x16_x3x1, 16 ); - xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC ); + xmm_x16_x2x0 = _mm_blend_epi16( xmm_x16_x2x0, xmm_x16_x3x1, 0xCC ); - _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 ); + _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x16_x2x0 ); } for( ; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); + x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 ); } - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ if( NSQ->rewhite_flag ) { if( subfr == 0 ) { @@ -671,9 +718,11 @@ static OPUS_INLINE void silk_nsq_scale_states_sse4_1( } /* Adjust for changing gain */ - if( gain_adj_Q16 != (opus_int32)1 << 16 ) { - /* Scale long-term shaping state */ + if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1; + gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); + + /* Scale long-term shaping state */ /* prepare gain_adj_Q16 in packed 4 32-bits */ xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16); @@ -707,6 +756,7 @@ static OPUS_INLINE void silk_nsq_scale_states_sse4_1( } NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); + NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 ); /* Scale short-term prediction and shaping states */ for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { @@ -715,5 +765,8 @@ static OPUS_INLINE void silk_nsq_scale_states_sse4_1( for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); } + + /* Save inverse gain */ + NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; } } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/SigProc_FIX_sse.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/SigProc_FIX_sse.h index 61efa8da4..89a5ec888 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/SigProc_FIX_sse.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/SigProc_FIX_sse.h @@ -26,13 +26,13 @@ */ #ifndef SIGPROC_FIX_SSE_H -#define SIGPROC_FIX_SSE_H +# define SIGPROC_FIX_SSE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif -#if defined(OPUS_X86_MAY_HAVE_SSE4_1) +# if defined(OPUS_X86_MAY_HAVE_SSE4_1) void silk_burg_modified_sse4_1( opus_int32 *res_nrg, /* O Residual energy */ opus_int *res_nrg_Q, /* O Residual energy Q value */ @@ -45,11 +45,13 @@ void silk_burg_modified_sse4_1( int arch /* I Run-time architecture */ ); -#if defined(OPUS_X86_PRESUME_SSE4_1) -#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ - ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) +# if defined(OPUS_X86_PRESUME_SSE4_1) + +# define OVERRIDE_silk_burg_modified +# define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ + ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) -#else +# elif defined(OPUS_HAVE_RTCD) extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])( opus_int32 *res_nrg, /* O Residual energy */ @@ -62,33 +64,36 @@ extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])( const opus_int D, /* I Order */ int arch /* I Run-time architecture */); -# define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ - ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) +# define OVERRIDE_silk_burg_modified +# define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \ + ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch)) -#endif +# endif -opus_int64 silk_inner_prod16_aligned_64_sse4_1( +opus_int64 silk_inner_prod16_sse4_1( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len ); -#if defined(OPUS_X86_PRESUME_SSE4_1) +# if defined(OPUS_X86_PRESUME_SSE4_1) -#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ - ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len)) +# define OVERRIDE_silk_inner_prod16 +# define silk_inner_prod16(inVec1, inVec2, len, arch) \ + ((void)(arch),silk_inner_prod16_sse4_1(inVec1, inVec2, len)) -#else +# elif defined(OPUS_HAVE_RTCD) -extern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])( +extern opus_int64 (*const SILK_INNER_PROD16_IMPL[OPUS_ARCHMASK + 1])( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len); -# define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \ - ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len)) +# define OVERRIDE_silk_inner_prod16 +# define silk_inner_prod16(inVec1, inVec2, len, arch) \ + ((*SILK_INNER_PROD16_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len)) -#endif -#endif +# endif +# endif #endif diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VAD_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VAD_sse4_1.c index d02ddf4ad..e7eaf9714 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VAD_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VAD_sse4_1.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2014, Cisco Systems, INC - Written by XiangMingZhu WeiZhou MinPeng YanWang +/* Copyright (c) 2014-2020, Cisco Systems, INC + Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -63,6 +63,14 @@ opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if s SAVE_STACK; +#ifdef OPUS_CHECK_ASM + silk_encoder_state psEncC_c; + opus_int ret_c; + + silk_memcpy( &psEncC_c, psEncC, sizeof( psEncC_c ) ); + ret_c = silk_VAD_GetSA_Q8_c( &psEncC_c, pIn ); +#endif + /* Safety checks */ silk_assert( VAD_N_BANDS == 4 ); celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); @@ -233,15 +241,14 @@ opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if s speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); } + if( psEncC->frame_length == 20 * psEncC->fs_kHz ) { + speech_nrg = silk_RSHIFT32( speech_nrg, 1 ); + } /* Power scaling */ if( speech_nrg <= 0 ) { SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); - } else if( speech_nrg < 32768 ) { - if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { - speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 ); - } else { - speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 ); - } + } else if( speech_nrg < 16384 ) { + speech_nrg = silk_LSHIFT32( speech_nrg, 16 ); /* square-root */ speech_nrg = silk_SQRT_APPROX( speech_nrg ); @@ -272,6 +279,11 @@ opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if s psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); } +#ifdef OPUS_CHECK_ASM + silk_assert( ret == ret_c ); + silk_assert( !memcmp( &psEncC_c, psEncC, sizeof( psEncC_c ) ) ); +#endif + RESTORE_STACK; return( ret ); } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VQ_WMat_EC_sse4_1.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VQ_WMat_EC_sse4_1.c index 74d6c6d0e..2c7d18d05 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VQ_WMat_EC_sse4_1.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/VQ_WMat_EC_sse4_1.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2014, Cisco Systems, INC - Written by XiangMingZhu WeiZhou MinPeng YanWang +/* Copyright (c) 2014-2020, Cisco Systems, INC + Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -38,105 +38,136 @@ /* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ void silk_VQ_WMat_EC_sse4_1( opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int32 *res_nrg_Q15, /* O best residual energy */ + opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int32 *XX_Q17, /* I correlation matrix */ + const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ - opus_int L /* I number of vectors in codebook */ + const opus_int L /* I number of vectors in codebook */ ) { opus_int k, gain_tmp_Q7; const opus_int8 *cb_row_Q7; - opus_int16 diff_Q14[ 5 ]; - opus_int32 sum1_Q14, sum2_Q16; + opus_int32 neg_xX_Q24[ 5 ]; + opus_int32 sum1_Q15, sum2_Q24; + opus_int32 bits_res_Q8, bits_tot_Q8; + __m128i v_XX_31_Q17, v_XX_42_Q17, v_cb_row_31_Q7, v_cb_row_42_Q7, v_acc1_Q24, v_acc2_Q24; + + /* Negate and convert to new Q domain */ + neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 ); + neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 ); + neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 ); + neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 ); + neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 ); + + v_XX_31_Q17 = _mm_loadu_si128( (__m128i *)(&XX_Q17[ 1 ] ) ); + v_XX_42_Q17 = _mm_shuffle_epi32( v_XX_31_Q17, _MM_SHUFFLE( 0, 3, 2, 1 ) ); - __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5; /* Loop over codebook */ - *rate_dist_Q14 = silk_int32_MAX; + *rate_dist_Q8 = silk_int32_MAX; + *res_nrg_Q15 = silk_int32_MAX; cb_row_Q7 = cb_Q7; + /* If things go really bad, at least *ind is set to something safe. */ + *ind = 0; for( k = 0; k < L; k++ ) { + opus_int32 penalty; gain_tmp_Q7 = cb_gain_Q7[k]; - - diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); - - C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] ); - C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] ); - C_tmp2 = _mm_slli_epi32( C_tmp2, 7 ); - C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 ); - - diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 ); - diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 ); - diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 ); - diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 ); - /* Weighted rate */ - sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); + /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */ + sum1_Q15 = SILK_FIX_CONST( 1.001, 15 ); /* Penalty for too large gain */ - sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 ); - - silk_assert( sum1_Q14 >= 0 ); - - /* first row of W_Q18 */ - C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) ); - C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 ); - C_tmp4 = _mm_srli_si128( C_tmp4, 2 ); - - C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ - C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */ - - C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 ); - C_tmp5 = _mm_srli_si128( C_tmp5, 2 ); - - C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 ); - C_tmp5 = _mm_slli_epi32( C_tmp5, 1 ); - - C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) ); - sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 ); - - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); - - /* second row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); - - /* third row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); - - /* fourth row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); - - /* last row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); - - silk_assert( sum1_Q14 >= 0 ); + penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 ); + + /* first row of XX_Q17 */ + v_cb_row_31_Q7 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] ); + v_cb_row_42_Q7 = _mm_shuffle_epi32( v_cb_row_31_Q7, _MM_SHUFFLE( 0, 3, 2, 1 ) ); + v_cb_row_31_Q7 = _mm_mul_epi32( v_XX_31_Q17, v_cb_row_31_Q7 ); + v_cb_row_42_Q7 = _mm_mul_epi32( v_XX_42_Q17, v_cb_row_42_Q7 ); + v_acc1_Q24 = _mm_add_epi64( v_cb_row_31_Q7, v_cb_row_42_Q7); + v_acc2_Q24 = _mm_shuffle_epi32( v_acc1_Q24, _MM_SHUFFLE( 1, 0, 3, 2 ) ); + v_acc1_Q24 = _mm_add_epi64( v_acc1_Q24, v_acc2_Q24); + sum2_Q24 = _mm_cvtsi128_si32( v_acc1_Q24 ); + sum2_Q24 = silk_ADD32( neg_xX_Q24[ 0 ], sum2_Q24 ); + sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] ); + sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] ); + + /* second row of XX_Q17 */ + sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] ); + sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] ); + sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] ); + + /* third row of XX_Q17 */ + sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] ); + sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] ); + sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] ); + + /* fourth row of XX_Q17 */ + sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] ); + sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] ); + sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] ); + + /* last row of XX_Q17 */ + sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 ); + sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] ); + sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] ); /* find best */ - if( sum1_Q14 < *rate_dist_Q14 ) { - *rate_dist_Q14 = sum1_Q14; - *ind = (opus_int8)k; - *gain_Q7 = gain_tmp_Q7; + if( sum1_Q15 >= 0 ) { + /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */ + bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) ); + /* In the following line we reduce the codelength component by half ("-1"); seems to slightly improve quality */ + bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 ); + if( bits_tot_Q8 <= *rate_dist_Q8 ) { + *rate_dist_Q8 = bits_tot_Q8; + *res_nrg_Q15 = sum1_Q15 + penalty; + *ind = (opus_int8)k; + *gain_Q7 = gain_tmp_Q7; + } } /* Go to next cbk vector */ cb_row_Q7 += LTP_ORDER; } + +#ifdef OPUS_CHECK_ASM + { + opus_int8 ind_c = 0; + opus_int32 res_nrg_Q15_c = 0; + opus_int32 rate_dist_Q8_c = 0; + opus_int gain_Q7_c = 0; + + silk_VQ_WMat_EC_c( + &ind_c, + &res_nrg_Q15_c, + &rate_dist_Q8_c, + &gain_Q7_c, + XX_Q17, + xX_Q17, + cb_Q7, + cb_gain_Q7, + cl_Q5, + subfr_len, + max_gain_Q7, + L + ); + + silk_assert( *ind == ind_c ); + silk_assert( *res_nrg_Q15 == res_nrg_Q15_c ); + silk_assert( *rate_dist_Q8 == rate_dist_Q8_c ); + silk_assert( *gain_Q7 == gain_Q7_c ); + } +#endif } diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/main_sse.h b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/main_sse.h index 2f15d4486..a01d7f6c7 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/main_sse.h +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/main_sse.h @@ -26,171 +26,169 @@ */ #ifndef MAIN_SSE_H -#define MAIN_SSE_H +# define MAIN_SSE_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif # if defined(OPUS_X86_MAY_HAVE_SSE4_1) -#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ -# define OVERRIDE_silk_VQ_WMat_EC - void silk_VQ_WMat_EC_sse4_1( opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int32 *res_nrg_Q15, /* O best residual energy */ + opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int32 *XX_Q17, /* I correlation matrix */ + const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ - opus_int L /* I number of vectors in codebook */ + const opus_int L /* I number of vectors in codebook */ ); -#if defined OPUS_X86_PRESUME_SSE4_1 +# if defined OPUS_X86_PRESUME_SSE4_1 -#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ - mu_Q9, max_gain_Q7, L, arch) \ - ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ - mu_Q9, max_gain_Q7, L)) +# define OVERRIDE_silk_VQ_WMat_EC +# define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, \ + subfr_len, max_gain_Q7, L, arch) \ + ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, \ + subfr_len, max_gain_Q7, L)) -#else +# elif defined(OPUS_HAVE_RTCD) extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])( opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int32 *res_nrg_Q15, /* O best residual energy */ + opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int32 *XX_Q17, /* I correlation matrix */ + const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ - opus_int L /* I number of vectors in codebook */ + const opus_int L /* I number of vectors in codebook */ ); -# define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ - mu_Q9, max_gain_Q7, L, arch) \ - ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \ - mu_Q9, max_gain_Q7, L)) +# define OVERRIDE_silk_VQ_WMat_EC +# define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, \ + subfr_len, max_gain_Q7, L, arch) \ + ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, \ + subfr_len, max_gain_Q7, L)) -#endif -#endif - -#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ -# define OVERRIDE_silk_NSQ +# endif void silk_NSQ_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); -#if defined OPUS_X86_PRESUME_SSE4_1 +# if defined OPUS_X86_PRESUME_SSE4_1 -#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ +# define OVERRIDE_silk_NSQ +# define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ + HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) -#else +# elif defined(OPUS_HAVE_RTCD) extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); -# define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ +# define OVERRIDE_silk_NSQ +# define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ + HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) -#endif - -# define OVERRIDE_silk_NSQ_del_dec +# endif void silk_NSQ_del_dec_sse4_1( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); -#if defined OPUS_X86_PRESUME_SSE4_1 +# if defined OPUS_X86_PRESUME_SSE4_1 -#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ - ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ +# define OVERRIDE_silk_NSQ_del_dec +# define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ + HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ + ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) -#else +# elif defined(OPUS_HAVE_RTCD) extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ); -# define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ - HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ - ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \ +# define OVERRIDE_silk_NSQ_del_dec +# define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ + HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \ + ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \ HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14)) -#endif -#endif +# endif void silk_noise_shape_quantizer( silk_nsq_state *NSQ, /* I/O NSQ state */ @@ -223,26 +221,27 @@ void silk_VAD_GetNoiseLevels( silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ ); -# define OVERRIDE_silk_VAD_GetSA_Q8 - opus_int silk_VAD_GetSA_Q8_sse4_1( silk_encoder_state *psEnC, const opus_int16 pIn[] ); -#if defined(OPUS_X86_PRESUME_SSE4_1) -#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn)) +# if defined(OPUS_X86_PRESUME_SSE4_1) -#else +# define OVERRIDE_silk_VAD_GetSA_Q8 +# define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn)) -# define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \ - ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn)) +# elif defined(OPUS_HAVE_RTCD) extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])( silk_encoder_state *psEnC, const opus_int16 pIn[]); -#endif +# define OVERRIDE_silk_VAD_GetSA_Q8 +# define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \ + ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn)) + +# endif # endif #endif diff --git a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/x86_silk_map.c b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/x86_silk_map.c index 32dcc3cab..70f60078c 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/x86_silk_map.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/silk/x86/x86_silk_map.c @@ -35,22 +35,22 @@ #include "pitch.h" #include "main.h" -#if !defined(OPUS_X86_PRESUME_SSE4_1) +#if defined(OPUS_HAVE_RTCD) && !defined(OPUS_X86_PRESUME_SSE4_1) #if defined(FIXED_POINT) #include "fixed/main_FIX.h" -opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )( +opus_int64 (*const SILK_INNER_PROD16_IMPL[ OPUS_ARCHMASK + 1 ] )( const opus_int16 *inVec1, const opus_int16 *inVec2, const opus_int len ) = { - silk_inner_prod16_aligned_64_c, /* non-sse */ - silk_inner_prod16_aligned_64_c, - silk_inner_prod16_aligned_64_c, - MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */ - MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ) /* avx */ + silk_inner_prod16_c, /* non-sse */ + silk_inner_prod16_c, + silk_inner_prod16_c, + MAY_HAVE_SSE4_1( silk_inner_prod16 ), /* sse4.1 */ + MAY_HAVE_SSE4_1( silk_inner_prod16 ) /* avx */ }; #endif @@ -66,23 +66,22 @@ opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )( MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */ }; -#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) = { silk_NSQ_c, /* non-sse */ silk_NSQ_c, @@ -90,21 +89,20 @@ void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )( MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */ }; -#endif -#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */ void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )( opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int32 *res_nrg_Q15, /* O best residual energy */ + opus_int32 *rate_dist_Q8, /* O best total bitrate */ opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int32 *XX_Q17, /* I correlation matrix */ + const opus_int32 *xX_Q17, /* I correlation vector */ const opus_int8 *cb_Q7, /* I codebook */ const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int subfr_len, /* I number of samples per subframe */ const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ - opus_int L /* I number of vectors in codebook */ + const opus_int L /* I number of vectors in codebook */ ) = { silk_VQ_WMat_EC_c, /* non-sse */ silk_VQ_WMat_EC_c, @@ -112,25 +110,23 @@ void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )( MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */ }; -#endif -#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */ void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int16 x16[], /* I Input */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ ) = { silk_NSQ_del_dec_c, /* non-sse */ silk_NSQ_del_dec_c, @@ -138,7 +134,6 @@ void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )( MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */ MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */ }; -#endif #if defined(FIXED_POINT) diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/analysis.c b/libfenrir/src/main/jni/audio/opus/libopus/src/analysis.c index cb46dec58..058328f0f 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/analysis.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/analysis.c @@ -31,7 +31,9 @@ #define ANALYSIS_C +#ifdef MLP_TRAINING #include +#endif #include "mathops.h" #include "kiss_fft.h" diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_decoder.c b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_decoder.c index 9113638a0..6520e748e 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_decoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_decoder.c @@ -278,7 +278,8 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, ec_dec_init(&dec,(unsigned char*)data,len); } else { audiosize = frame_size; - mode = st->prev_mode; + /* Run PLC using last used mode (CELT if we ended with CELT redundancy) */ + mode = st->prev_redundancy ? MODE_CELT_ONLY : st->prev_mode; bandwidth = 0; if (mode == 0) @@ -419,7 +420,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, start_band = 0; if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL - && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) + && ec_tell(&dec)+17+20*(mode == MODE_HYBRID) <= 8*len) { /* Check if we have a redundant 0-8 kHz band */ if (mode == MODE_HYBRID) @@ -499,6 +500,11 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) { + /* If the previous frame did not use CELT (the first redundancy frame in + a transition from SILK may have been lost) then the CELT decoder is + stale at this point and the redundancy audio is not useful, however + the final range is still needed (for testing), so the redundancy is + always decoded but the decoded audio may not be used */ MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); @@ -561,7 +567,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); } - if (redundancy && celt_to_silk) + /* 5ms redundant frame for CELT->SILK; ignore if the previous frame did not + use CELT (the first redundancy frame in a transition from SILK may have + been lost) */ + if (redundancy && celt_to_silk && (st->prev_mode != MODE_SILK_ONLY || st->prev_redundancy)) { for (c=0;cchannels;c++) { diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_encoder.c b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_encoder.c index e98ac5b8d..8c8db5a54 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_encoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_encoder.c @@ -87,6 +87,7 @@ struct OpusEncoder { int lfe; int arch; int use_dtx; /* general DTX for both SILK and CELT */ + int fec_config; #ifndef DISABLE_FLOAT_API TonalityAnalysisState analysis; #endif @@ -112,7 +113,7 @@ struct OpusEncoder { opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; #ifndef DISABLE_FLOAT_API int detected_bandwidth; - int nb_no_activity_frames; + int nb_no_activity_ms_Q1; opus_val32 peak_signal_energy; #endif int nonfinal_frame; /* current frame is not the final in a packet */ @@ -892,44 +893,29 @@ static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, in #endif /* Decides if DTX should be turned on (=1) or off (=0) */ -static int decide_dtx_mode(float activity_probability, /* probability that current frame contains speech/music */ - int *nb_no_activity_frames, /* number of consecutive frames with no activity */ - opus_val32 peak_signal_energy, /* peak energy of desired signal detected so far */ - const opus_val16 *pcm, /* input pcm signal */ - int frame_size, /* frame size */ - int channels, - int is_silence, /* only digital silence detected in this frame */ - int arch - ) -{ - opus_val32 noise_energy; - - if (!is_silence) - { - if (activity_probability < DTX_ACTIVITY_THRESHOLD) /* is noise */ - { - noise_energy = compute_frame_energy(pcm, frame_size, channels, arch); +static int decide_dtx_mode(opus_int activity, /* indicates if this frame contains speech/music */ + int *nb_no_activity_ms_Q1, /* number of consecutive milliseconds with no activity, in Q1 */ + int frame_size_ms_Q1 /* number of miliseconds in this update, in Q1 */ + ) - /* but is sufficiently quiet */ - is_silence = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy); - } - } - - if (is_silence) +{ + if (!activity) { - /* The number of consecutive DTX frames should be within the allowed bounds */ - (*nb_no_activity_frames)++; - - if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX) + /* The number of consecutive DTX frames should be within the allowed bounds. + Note that the allowed bound is defined in the SILK headers and assumes 20 ms + frames. As this function can be called with any frame length, a conversion to + milliseconds is done before the comparisons. */ + (*nb_no_activity_ms_Q1) += frame_size_ms_Q1; + if (*nb_no_activity_ms_Q1 > NB_SPEECH_FRAMES_BEFORE_DTX*20*2) { - if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX)) + if (*nb_no_activity_ms_Q1 <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX)*20*2) /* Valid frame for DTX! */ return 1; else - (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX; + (*nb_no_activity_ms_Q1) = NB_SPEECH_FRAMES_BEFORE_DTX*20*2; } } else - (*nb_no_activity_frames) = 0; + (*nb_no_activity_ms_Q1) = 0; return 0; } @@ -1102,6 +1088,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ int analysis_read_subframe_bak=-1; int is_silence = 0; #endif + opus_int activity = VAD_NO_DECISION; + VARDECL(opus_val16, tmp_prefill); ALLOC_STACK; @@ -1169,6 +1157,20 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ if (!is_silence) st->voice_ratio = -1; + if (is_silence) + { + activity = !is_silence; + } else if (analysis_info.valid) + { + activity = analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD; + if (!activity) + { + /* Mark as active if this noise frame is sufficiently loud */ + opus_val32 noise_energy = compute_frame_energy(pcm, frame_size, st->channels, st->arch); + activity = st->peak_signal_energy < (PSEUDO_SNR_THRESHOLD * noise_energy); + } + } + st->detected_bandwidth = 0; if (analysis_info.valid) { @@ -1313,6 +1315,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ st->stream_channels = st->force_channels; } else { #ifdef FUZZING + (void)stereo_music_threshold; + (void)stereo_voice_threshold; /* Random mono/stereo decision */ if (st->channels == 2 && (rand()&0x1F)==0) st->stream_channels = 3-st->stream_channels; @@ -1351,6 +1355,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ } else if (st->user_forced_mode == OPUS_AUTO) { #ifdef FUZZING + (void)stereo_width; + (void)mode_thresholds; /* Random mode switching */ if ((rand()&0xF)==0) { @@ -1388,8 +1394,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; - /* When FEC is enabled and there's enough packet loss, use SILK */ - if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) + /* When FEC is enabled and there's enough packet loss, use SILK. + Unless the FEC is set to 2, in which case we don't switch to SILK if we're confident we have music. */ + if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4 && (st->fec_config != 2 || voice_est > 25)) st->mode = MODE_SILK_ONLY; /* When encoding voice and DTX is enabled but the generalized DTX cannot be used, use SILK in order to make use of its DTX. */ @@ -1668,7 +1675,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ if (st->mode != MODE_CELT_ONLY) { opus_int32 total_bitRate, celt_rate; - opus_int activity; #ifdef FIXED_POINT const opus_int16 *pcm_silk; #else @@ -1676,14 +1682,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ ALLOC(pcm_silk, st->channels*frame_size, opus_int16); #endif - activity = VAD_NO_DECISION; -#ifndef DISABLE_FLOAT_API - if( analysis_info.valid ) { - /* Inform SILK about the Opus VAD decision */ - activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD ); - } -#endif - /* Distribute bits between SILK and CELT */ total_bitRate = 8 * bytes_target * frame_rate; if( st->mode == MODE_HYBRID ) { @@ -2144,8 +2142,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ #ifndef DISABLE_FLOAT_API if (st->use_dtx && (analysis_info.valid || is_silence)) { - if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames, - st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch)) + if (decide_dtx_mode(activity, &st->nb_no_activity_ms_Q1, 2*1000*frame_size/st->Fs)) { st->rangeFinal = 0; data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); @@ -2153,7 +2150,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ return 1; } } else { - st->nb_no_activity_frames = 0; + st->nb_no_activity_ms_Q1 = 0; } #endif @@ -2448,11 +2445,12 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) case OPUS_SET_INBAND_FEC_REQUEST: { opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) + if(value<0 || value>2) { goto bad_arg; } - st->silk_mode.useInBandFEC = value; + st->fec_config = value; + st->silk_mode.useInBandFEC = (value != 0); } break; case OPUS_GET_INBAND_FEC_REQUEST: @@ -2462,7 +2460,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) { goto bad_arg; } - *value = st->silk_mode.useInBandFEC; + *value = st->fec_config; } break; case OPUS_SET_PACKET_LOSS_PERC_REQUEST: @@ -2736,17 +2734,17 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) } if (st->silk_mode.useDTX && (st->prev_mode == MODE_SILK_ONLY || st->prev_mode == MODE_HYBRID)) { /* DTX determined by Silk. */ - int n; - void *silk_enc = (char*)st+st->silk_enc_offset; - *value = 1; - for (n=0;nsilk_mode.nChannelsInternal;n++) { - *value = *value && ((silk_encoder*)silk_enc)->state_Fxx[n].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX; + silk_encoder *silk_enc = (silk_encoder*)(void *)((char*)st+st->silk_enc_offset); + *value = silk_enc->state_Fxx[0].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX; + /* Stereo: check second channel unless only the middle channel was encoded. */ + if(*value == 1 && st->silk_mode.nChannelsInternal == 2 && silk_enc->prev_decode_only_middle == 0) { + *value = silk_enc->state_Fxx[1].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX; } } #ifndef DISABLE_FLOAT_API else if (st->use_dtx) { /* DTX determined by Opus. */ - *value = st->nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX; + *value = st->nb_no_activity_ms_Q1 >= NB_SPEECH_FRAMES_BEFORE_DTX*20*2; } #endif else { @@ -2754,7 +2752,6 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) } } break; - case CELT_GET_MODE_REQUEST: { const CELTMode ** value = va_arg(ap, const CELTMode**); diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_decoder.c b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_decoder.c index 0018517ae..a2837c354 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_decoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_decoder.c @@ -251,8 +251,11 @@ int opus_multistream_decode_native( } packet_offset = 0; ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); - data += packet_offset; - len -= packet_offset; + if (!do_plc) + { + data += packet_offset; + len -= packet_offset; + } if (ret <= 0) { RESTORE_STACK; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_encoder.c b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_encoder.c index 93204a14c..213e3eb2c 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_encoder.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/opus_multistream_encoder.c @@ -443,7 +443,8 @@ static int opus_multistream_encoder_init_impl( char *ptr; if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) + (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || + (streams+coupled_streams>channels)) return OPUS_BAD_ARG; st->arch = opus_select_arch(); @@ -459,8 +460,7 @@ static int opus_multistream_encoder_init_impl( st->layout.mapping[i] = mapping[i]; if (!validate_layout(&st->layout)) return OPUS_BAD_ARG; - if (mapping_type == MAPPING_TYPE_SURROUND && - !validate_encoder_layout(&st->layout)) + if (!validate_encoder_layout(&st->layout)) return OPUS_BAD_ARG; if (mapping_type == MAPPING_TYPE_AMBISONICS && !validate_ambisonics(st->layout.nb_channels, NULL, NULL)) @@ -595,7 +595,8 @@ OpusMSEncoder *opus_multistream_encoder_create( int ret; OpusMSEncoder *st; if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams)) + (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || + (streams+coupled_streams>channels)) { if (error) *error = OPUS_BAD_ARG; diff --git a/libfenrir/src/main/jni/audio/opus/libopus/src/repacketizer_demo.c b/libfenrir/src/main/jni/audio/opus/libopus/src/repacketizer_demo.c index dc05c1b35..43de70192 100644 --- a/libfenrir/src/main/jni/audio/opus/libopus/src/repacketizer_demo.c +++ b/libfenrir/src/main/jni/audio/opus/libopus/src/repacketizer_demo.c @@ -119,7 +119,19 @@ int main(int argc, char *argv[]) for (i=0;i1500 || len[i]<0) @@ -135,13 +147,31 @@ int main(int argc, char *argv[]) } break; } - err = fread(ch, 1, 4, fin); - rng[i] = char_to_int(ch); - err = fread(packets[i], 1, len[i], fin); - if (feof(fin)) + if (fread(ch, 1, 4, fin)!=4) { - eof = 1; - break; + if (feof(fin)) + { + eof = 1; + } else { + fprintf(stderr, "Error reading.\n"); + fclose(fin); + fclose(fout); + return EXIT_FAILURE; + } + break; + } + rng[i] = char_to_int(ch); + if (fread(packets[i], len[i], 1, fin)!=1) { + if (feof(fin)) + { + eof = 1; + } else { + fprintf(stderr, "Error reading packet of %u bytes.\n", len[i]); + fclose(fin); + fclose(fout); + return EXIT_FAILURE; + } + break; } err = opus_repacketizer_cat(rp, packets[i], len[i]); if (err!=OPUS_OK) diff --git a/libfenrir/src/main/jni/compress/zstd/jni_zstd.c b/libfenrir/src/main/jni/compress/zstd/jni_zstd.c index d8c8def98..55489ecda 100644 --- a/libfenrir/src/main/jni/compress/zstd/jni_zstd.c +++ b/libfenrir/src/main/jni/compress/zstd/jni_zstd.c @@ -332,6 +332,17 @@ JNIEXPORT jint JNICALL Java_com_github_luben_zstd_Zstd_setCompressionWorkers return ZSTD_CCtx_setParameter((ZSTD_CCtx *)(intptr_t) stream, ZSTD_c_nbWorkers, workers); } +/* + * Class: com_github_luben_zstd_Zstd + * Method: setRefMultipleDDicts + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_com_github_luben_zstd_Zstd_setRefMultipleDDicts + (JNIEnv *env, jclass obj, jlong stream, jboolean enabled) { + ZSTD_refMultipleDDicts_e value = enabled ? ZSTD_rmd_refMultipleDDicts : ZSTD_rmd_refSingleDDict; + return ZSTD_DCtx_setParameter((ZSTD_DCtx *)(intptr_t) stream, ZSTD_d_refMultipleDDicts, value); +} + /* * Class: com_github_luben_zstd_Zstd * Methods: header constants access diff --git a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/biginteger.h b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/biginteger.h index af4873803..4930043dc 100644 --- a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/biginteger.h +++ b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/biginteger.h @@ -259,7 +259,7 @@ class BigInteger { if (low < k) (*outHigh)++; return low; -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) __extension__ typedef unsigned __int128 uint128; uint128 p = static_cast(a) * static_cast(b); p += k; diff --git a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/diyfp.h b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/diyfp.h index f7d46539a..1f60fb60c 100644 --- a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/diyfp.h +++ b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/internal/diyfp.h @@ -79,7 +79,7 @@ struct DiyFp { if (l & (uint64_t(1) << 63)) // rounding h++; return DiyFp(h, e + rhs.e + 64); -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__) __extension__ typedef unsigned __int128 uint128; uint128 p = static_cast(f) * static_cast(rhs.f); uint64_t h = static_cast(p >> 64); diff --git a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/pointer.h b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/pointer.h index 05b1704dd..6f4ef3892 100644 --- a/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/pointer.h +++ b/libfenrir/src/main/jni/rlottie/src/lottie/rapidjson/pointer.h @@ -890,10 +890,16 @@ class GenericPointer { std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch)); } - // Adjust pointers to name buffer - std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_; - for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t) - t->name += diff; + // The names of each token point to a string in the nameBuffer_. The + // previous memcpy copied over string pointers into the rhs.nameBuffer_, + // but they should point to the strings in the new nameBuffer_. + for (size_t i = 0; i < rhs.tokenCount_; ++i) { + // The offset between the string address and the name buffer should + // still be constant, so we can just get this offset and set each new + // token name according the new buffer start + the known offset. + std::ptrdiff_t name_offset = rhs.tokens_[i].name - rhs.nameBuffer_; + tokens_[i].name = nameBuffer_ + name_offset; + } return nameBuffer_ + nameBufferSize; } diff --git a/libfenrir/src/main/jni/thorvg/inc/thorvg.h b/libfenrir/src/main/jni/thorvg/inc/thorvg.h index c2fcc8023..dd5c05fe7 100644 --- a/libfenrir/src/main/jni/thorvg/inc/thorvg.h +++ b/libfenrir/src/main/jni/thorvg/inc/thorvg.h @@ -23,32 +23,36 @@ #undef TVG_API #endif -#if defined(_WIN32) && !defined(__clang__) - #if TVG_BUILD - #if TVG_EXPORT +#ifndef TVG_STATIC + #ifdef _WIN32 + #if TVG_BUILD #define TVG_API __declspec(dllexport) #else - #define TVG_API + #define TVG_API __declspec(dllimport) #endif + #elif (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) + #define TVG_API __global #else - #define TVG_API __declspec(dllimport) - #endif - #define TVG_DEPRECATED __declspec(deprecated) -#else - #if TVG_BUILD - #if TVG_EXPORT - #define TVG_API __attribute__ ((visibility ("default"))) + #if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__INTEL_COMPILER) + #define TVG_API __attribute__ ((visibility("default"))) #else #define TVG_API #endif - #else - #define TVG_API #endif - #define TVG_DEPRECATED __attribute__ ((__deprecated__)) +#else + #define TVG_API #endif -#ifdef __cplusplus -extern "C" { +#ifdef TVG_DEPRECATED + #undef TVG_DEPRECATED +#endif + +#ifdef _WIN32 + #define TVG_DEPRECATED __declspec(deprecated) +#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) + #define TVG_DEPRECATED __attribute__ ((__deprecated__)) +#else + #define TVG_DEPRECATED #endif #define _TVG_DECLARE_PRIVATE(A) \ @@ -164,7 +168,7 @@ enum class CompositeMethod ClipPath, ///< The intersection of the source and the target is determined and only the resulting pixels from the source are rendered. AlphaMask, ///< The pixels of the source and the target are alpha blended. As a result, only the part of the source, which alpha intersects with the target is visible. InvAlphaMask, ///< The pixels of the source and the complement to the target's pixels are alpha blended. As a result, only the part of the source which alpha is not covered by the target is visible. - LumaMask ///< @BETA_API The source pixels are converted to the grayscale (luma value) and alpha blended with the target. As a result, only the part of the source, which intersects with the target is visible. + LumaMask ///< The source pixels are converted to the grayscale (luma value) and alpha blended with the target. As a result, only the part of the source, which intersects with the target is visible. @since 0.9 }; /** @@ -321,21 +325,6 @@ class TVG_API Paint */ Result composite(std::unique_ptr target, CompositeMethod method) noexcept; - /** - * @brief Gets the bounding box of the paint object before any transformation. - * - * @param[out] x The x coordinate of the upper left corner of the object. - * @param[out] y The y coordinate of the upper left corner of the object. - * @param[out] w The width of the object. - * @param[out] h The height of the object. - * - * @return Result::Success when succeed, Result::InsufficientCondition otherwise. - * - * @note The bounding box doesn't indicate the final rendered region. It's the smallest rectangle that encloses the object. - * @see Paint::bounds(float* x, float* y, float* w, float* h, bool transformed); - */ - TVG_DEPRECATED Result bounds(float* x, float* y, float* w, float* h) const noexcept; - /** * @brief Gets the axis-aligned bounding box of the paint object. * @@ -1145,24 +1134,6 @@ class TVG_API Picture final : public Paint */ Result load(const std::string& path) noexcept; - /** - * @brief Loads a picture data from a memory block of a given size. - * - * @param[in] data A pointer to a memory location where the content of the picture file is stored. - * @param[in] size The size in bytes of the memory occupied by the @p data. - * @param[in] copy Decides whether the data should be copied into the engine local buffer. - * - * @retval Result::Success When succeed. - * @retval Result::InvalidArguments In case no data are provided or the @p size is zero or less. - * @retval Result::NonSupport When trying to load a file with an unknown extension. - * @retval Result::Unknown If an error occurs at a later stage. - * - * @warning: you have responsibility to release the @p data memory if the @p copy is true - * @deprecated Use load(const char* data, uint32_t size, const std::string& mimeType, bool copy) instead. - * @see Result load(const char* data, uint32_t size, const std::string& mimeType, bool copy = false) noexcept - */ - TVG_DEPRECATED Result load(const char* data, uint32_t size, bool copy = false) noexcept; - /** * @brief Loads a picture data from a memory block of a given size. * @@ -1219,9 +1190,10 @@ class TVG_API Picture final : public Paint /** * @brief Loads a raw data from a memory block with a given size. * - * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * @retval Result::Success When succeed, Result::InsufficientCondition otherwise. + * @retval Result::FailedAllocation An internal error possibly with memory allocation. * - * @BETA_API + * @since 0.9 */ Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept; @@ -1661,12 +1633,32 @@ class TVG_API Accessor final _TVG_DECLARE_PRIVATE(Accessor); }; -/** @}*/ -} //namespace +/** + * @brief The cast() function is a utility function used to cast a 'Paint' to type 'T'. + * + * @BETA_API + */ +template +std::unique_ptr cast(Paint* paint) +{ + return std::unique_ptr(static_cast(paint)); +} -#ifdef __cplusplus +/** + * @brief The cast() function is a utility function used to cast a 'Fill' to type 'T'. + * + * @BETA_API + */ +template +std::unique_ptr cast(Fill* fill) +{ + return std::unique_ptr(static_cast(fill)); } -#endif + + +/** @}*/ + +} //namespace #endif //_THORVG_H_ diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwCommon.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwCommon.h index 04b56ffdf..0e9029bf7 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwCommon.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwCommon.h @@ -223,11 +223,16 @@ struct SwImage { SwOutline* outline = nullptr; SwRleData* rle = nullptr; - uint32_t* data = nullptr; + union { + pixel_t* data; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale + }; uint32_t w, h, stride; int32_t ox = 0; //offset x int32_t oy = 0; //offset y float scale; + uint8_t channelSize; bool direct = false; //draw image directly (with offset) bool scaled = false; //draw scaled image @@ -236,7 +241,7 @@ struct SwImage struct SwBlender { uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); - uint32_t (*lumaValue)(uint32_t c); + uint8_t (*luma)(uint8_t* c); }; struct SwCompositor; @@ -356,7 +361,7 @@ bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8 bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint32_t opacity); bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id); -bool rasterClear(SwSurface* surface); +bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len); void rasterUnpremultiply(Surface* surface); void rasterPremultiply(Surface* surface); diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRaster.cpp index 41416dfff..2e29c1758 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRaster.cpp +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRaster.cpp @@ -37,8 +37,8 @@ /************************************************************************/ constexpr auto DOWN_SCALE_TOLERANCE = 0.5f; - -static inline uint32_t _multiplyAlpha(uint32_t c, uint32_t a) +template +static inline T _multiply(T c, T a) { return ((c * a + 0xff) >> 8); } @@ -56,15 +56,29 @@ static inline uint32_t _ialpha(uint32_t c) } -static inline uint32_t _abgrLumaValue(uint32_t c) +static inline uint8_t _alpha(uint8_t* a) +{ + return *a; +} + + +static inline uint8_t _ialpha(uint8_t* a) +{ + return ~(*a); +} + + +static inline uint8_t _abgrLuma(uint8_t* c) { - return ((((c&0xff)*54) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*19))) >> 8; //0.2125*R + 0.7154*G + 0.0721*B + auto v = *(uint32_t*)c; + return ((((v&0xff)*54) + (((v>>8)&0xff)*183) + (((v>>16)&0xff)*19))) >> 8; //0.2125*R + 0.7154*G + 0.0721*B } -static inline uint32_t _argbLumaValue(uint32_t c) +static inline uint8_t _argbLuma(uint8_t* c) { - return ((((c&0xff)*19) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*54))) >> 8; //0.0721*B + 0.7154*G + 0.2125*R + auto v = *(uint32_t*)c; + return ((((v&0xff)*19) + (((v>>8)&0xff)*183) + (((v>>16)&0xff)*54))) >> 8; //0.0721*B + 0.7154*G + 0.2125*R } @@ -148,65 +162,95 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t } +void _rasterGrayscale8(uint8_t *dst, uint32_t val, uint32_t offset, int32_t len) +{ + cRasterPixels(dst, val, offset, len); +} + /************************************************************************/ /* Rect */ /************************************************************************/ -static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t(*blender)(uint8_t*)) { - TVGLOG("SW_ENGINE", "Masked Rect"); - - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); - - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer - - for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface->stride]; - auto cmp = &cbuffer[y * surface->stride]; - for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp) { - auto tmp = ALPHA_BLEND(color, blendMethod(*cmp)); - *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + ((region.min.y * surface->compositor->image.stride + region.min.x) * csize); //compositor buffer + + TVGLOG("SW_ENGINE", "Masked Rect [Region: %lu %lu %u %u]", region.min.x, region.min.y, w, h); + + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + auto cmp = &cbuffer[y * surface->stride * csize]; + for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { + auto tmp = ALPHA_BLEND(color, blender(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + //8bits grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + auto cmp = &cbuffer[y * surface->stride * csize]; + for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { + auto tmp = _multiply(a, blender(cmp)); + *dst = tmp + _multiply(*dst, _ialpha(tmp)); + } } } return true; } -static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint32_t color) +static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b) { - auto buffer = surface->buffer + (region.min.y * surface->stride); auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); - for (uint32_t y = 0; y < h; ++y) { - rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w); + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, 255); + auto buffer = surface->buf32 + (region.min.y * surface->stride); + for (uint32_t y = 0; y < h; ++y) { + rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w); + } + //8bits grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride); + for (uint32_t y = 0; y < h; ++y) { + _rasterGrayscale8(buffer + y * surface->stride, 255, region.min.x, w); + } } return true; } -static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color, uint8_t opacity) +static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (_compositing(surface)) { if (surface->compositor->method == CompositeMethod::AlphaMask) { - return _rasterMaskedRect(surface, region, color, _alpha); + return _rasterMaskedRect(surface, region, r, g, b, a, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { - return _rasterMaskedRect(surface, region, color, _ialpha); + return _rasterMaskedRect(surface, region, r, g, b, a, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterMaskedRect(surface, region, color, surface->blender.lumaValue); + return _rasterMaskedRect(surface, region, r, g, b, a, surface->blender.luma); } } else { - if (opacity == 255) { - return _rasterSolidRect(surface, region, color); + if (a == 255) { + return _rasterSolidRect(surface, region, r, g, b); } else { #if defined(THORVG_AVX_VECTOR_SUPPORT) - return avxRasterTranslucentRect(surface, region, color); + return avxRasterTranslucentRect(surface, region, r, g, b, a); #elif defined(THORVG_NEON_VECTOR_SUPPORT) - return neonRasterTranslucentRect(surface, region, color); + return neonRasterTranslucentRect(surface, region, r, g, b, a); #else - return cRasterTranslucentRect(surface, region, color); + return cRasterTranslucentRect(surface, region, r, g, b, a); #endif } } @@ -218,41 +262,74 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color /* Rle */ /************************************************************************/ -static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterMaskedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Masked Rle"); auto span = rle->spans; uint32_t src; - auto cbuffer = surface->compositor->image.data; - - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; - if (span->coverage == 255) src = color; - else src = ALPHA_BLEND(color, span->coverage); - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) { - auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); - *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + auto cbuffer = surface->compositor->image.buf8; + auto csize = surface->compositor->image.channelSize; + + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, a); + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + if (span->coverage == 255) src = color; + else src = ALPHA_BLEND(color, span->coverage); + for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { + auto tmp = ALPHA_BLEND(src, blender(cmp)); + *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + if (span->coverage == 255) src = a; + else src = _multiply(a, span->coverage); + for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { + auto tmp = _multiply(src, blender(cmp)); + *dst = tmp + _multiply(*dst, _ialpha(tmp)); + } } } return true; } -static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b) { auto span = rle->spans; - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - if (span->coverage == 255) { - rasterRGBA32(surface->buffer + span->y * surface->stride, color, span->x, span->len); - } else { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto src = ALPHA_BLEND(color, span->coverage); - auto ialpha = 255 - span->coverage; - for (uint32_t x = 0; x < span->len; ++x, ++dst) { - *dst = src + ALPHA_BLEND(*dst, ialpha); + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, 255); + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + rasterRGBA32(surface->buf32 + span->y * surface->stride, color, span->x, span->len); + } else { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto src = ALPHA_BLEND(color, span->coverage); + auto ialpha = 255 - span->coverage; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, ialpha); + } + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + if (span->coverage == 255) { + _rasterGrayscale8(surface->buf8 + span->y * surface->stride, 255, span->x, span->len); + } else { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = span->coverage; + } } } } @@ -260,28 +337,28 @@ static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint32_t c } -static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8_t opacity) +static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (!rle) return false; if (_compositing(surface)) { if (surface->compositor->method == CompositeMethod::AlphaMask) { - return _rasterMaskedRle(surface, rle, color, _alpha); + return _rasterMaskedRle(surface, rle, r, g, b, a, _alpha); } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { - return _rasterMaskedRle(surface, rle, color, _ialpha); + return _rasterMaskedRle(surface, rle, r, g, b, a, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterMaskedRle(surface, rle, color, surface->blender.lumaValue); + return _rasterMaskedRle(surface, rle, r, g, b, a, surface->blender.luma); } } else { - if (opacity == 255) { - return _rasterSolidRle(surface, rle, color); + if (a == 255) { + return _rasterSolidRle(surface, rle, r, g, b); } else { #if defined(THORVG_AVX_VECTOR_SUPPORT) - return avxRasterTranslucentRle(surface, rle, color); + return avxRasterTranslucentRle(surface, rle, r, g, b, a); #elif defined(THORVG_NEON_VECTOR_SUPPORT) - return neonRasterTranslucentRle(surface, rle, color); + return neonRasterTranslucentRle(surface, rle, r, g, b, a); #else - return cRasterTranslucentRle(surface, rle, color); + return cRasterTranslucentRle(surface, rle, r, g, b, a); #endif } } @@ -301,7 +378,7 @@ static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, c } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, surface->blender.lumaValue); + return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, surface->blender.luma); } } else { return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, nullptr); @@ -313,25 +390,26 @@ static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, c /* RLE Scaled RGBA Image */ /************************************************************************/ -static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Scaled Masked Translucent Rle Image"); auto span = image->rle->spans; + auto csize = surface->compositor->image.channelSize; //Center (Down-Scaled) if (image->scale < DOWN_SCALE_TOLERANCE) { for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); if (sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; - auto alpha = _multiplyAlpha(span->coverage, opacity); - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto alpha = _multiply(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); - auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + auto tmp = ALPHA_BLEND(src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -340,14 +418,14 @@ static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = span->y * itransform->e22 + itransform->e23; if ((uint32_t)sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; - auto alpha = _multiplyAlpha(span->coverage, opacity); - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto alpha = _multiply(span->coverage, opacity); + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); - auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), alpha); + auto tmp = ALPHA_BLEND(src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -356,32 +434,33 @@ static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const } -static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Scaled Masked Rle Image"); auto span = image->rle->spans; + auto csize = surface->compositor->image.channelSize; //Center (Down-Scaled) if (image->scale < DOWN_SCALE_TOLERANCE) { for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); if (sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize]; if (span->coverage == 255) { - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto tmp = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp)); + auto tmp = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); - auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); + auto tmp = ALPHA_BLEND(src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -391,21 +470,21 @@ static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* i for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = span->y * itransform->e22 + itransform->e23; if ((uint32_t)sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &surface->compositor->image.buf8[(span->y * surface->compositor->image.stride + span->x) * csize]; if (span->coverage == 255) { - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto tmp = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp)); + auto tmp = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { - for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, ++cmp) { + for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst, cmp += csize) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), span->coverage); - auto tmp = ALPHA_BLEND(src, blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), span->coverage); + auto tmp = ALPHA_BLEND(src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -424,12 +503,12 @@ static bool _rasterScaledTranslucentRleRGBAImage(SwSurface* surface, const SwIma for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); if (sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto alpha = _multiplyAlpha(span->coverage, opacity); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto alpha = _multiply(span->coverage, opacity); for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -438,12 +517,12 @@ static bool _rasterScaledTranslucentRleRGBAImage(SwSurface* surface, const SwIma for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = span->y * itransform->e22 + itransform->e23; if ((uint32_t)sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto alpha = _multiplyAlpha(span->coverage, opacity); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto alpha = _multiply(span->coverage, opacity); for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), alpha); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -461,19 +540,19 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image, for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = (uint32_t)(span->y * itransform->e22 + itransform->e23); if (sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; if (span->coverage == 255) { for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = _interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale); + auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } else { for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), span->coverage); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -483,19 +562,19 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image, for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { auto sy = span->y * itransform->e22 + itransform->e23; if ((uint32_t)sy >= image->h) continue; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; if (span->coverage == 255) { for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy); + auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } else { for (uint32_t x = static_cast(span->x); x < static_cast(span->x) + span->len; ++x, ++dst) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), span->coverage); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), span->coverage); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -522,7 +601,7 @@ static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue); + return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.luma); } } else { if (surface->compositor->method == CompositeMethod::AlphaMask) { @@ -530,7 +609,7 @@ static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue); + return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.luma); } } } else { @@ -545,26 +624,27 @@ static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const /* RLE Direct RGBA Image */ /************************************************************************/ -static bool _rasterDirectMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterDirectMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Direct Masked Rle Image"); auto span = image->rle->spans; - auto cbuffer = surface->compositor->image.data; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; - auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); - auto alpha = _multiplyAlpha(span->coverage, opacity); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = _multiply(span->coverage, opacity); if (alpha == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { - auto tmp = ALPHA_BLEND(*img, blendMethod(*cmp)); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { - auto tmp = ALPHA_BLEND(*img, _multiplyAlpha(alpha, blendMethod(*cmp))); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, _multiply(alpha, blender(cmp))); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -573,25 +653,26 @@ static bool _rasterDirectMaskedTranslucentRleRGBAImage(SwSurface* surface, const } -static bool _rasterDirectMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterDirectMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Direct Masked Rle Image"); auto span = image->rle->spans; - auto cbuffer = surface->compositor->image.data; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; - auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); if (span->coverage == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { - auto tmp = ALPHA_BLEND(*img, blendMethod(*cmp)); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) { - auto tmp = ALPHA_BLEND(*img, _multiplyAlpha(span->coverage, blendMethod(*cmp))); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img, cmp += csize) { + auto tmp = ALPHA_BLEND(*img, _multiply(span->coverage, blender(cmp))); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -605,9 +686,9 @@ static bool _rasterDirectTranslucentRleRGBAImage(SwSurface* surface, const SwIma auto span = image->rle->spans; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); - auto alpha = _multiplyAlpha(span->coverage, opacity); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto alpha = _multiply(span->coverage, opacity); for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { auto src = ALPHA_BLEND(*img, alpha); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); @@ -622,8 +703,8 @@ static bool _rasterDirectRleRGBAImage(SwSurface* surface, const SwImage* image) auto span = image->rle->spans; for (uint32_t i = 0; i < image->rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox); + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto img = image->buf32 + (span->y + image->oy) * image->stride + (span->x + image->ox); if (span->coverage == 255) { for (uint32_t x = 0; x < span->len; ++x, ++dst, ++img) { *dst = *img + ALPHA_BLEND(*dst, _ialpha(*img)); @@ -648,7 +729,7 @@ static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32 } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterDirectMaskedRleRGBAImage(surface, image, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.lumaValue); + return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.luma); } } else { if (surface->compositor->method == CompositeMethod::AlphaMask) { @@ -656,7 +737,7 @@ static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32 } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.lumaValue); + return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.luma); } } } else { @@ -679,7 +760,7 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, surface->blender.lumaValue); + return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, surface->blender.luma); } } else { return _rasterTexmapPolygon(surface, image, transform, ®ion, opacity, nullptr); @@ -695,7 +776,7 @@ static bool _transformedRGBAImageMesh(SwSurface* surface, const SwImage* image, } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, surface->blender.lumaValue); + return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, surface->blender.luma); } } else { return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, nullptr); @@ -708,13 +789,13 @@ static bool _transformedRGBAImageMesh(SwSurface* surface, const SwImage* image, /*Scaled RGBA Image */ /************************************************************************/ - -static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint8_t(*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Scaled Masked Image"); - auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride + region.min.x); + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; // Down-Scaled if (image->scale < DOWN_SCALE_TOLERANCE) { @@ -723,15 +804,15 @@ static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const Sw if (sy >= image->h) continue; auto dst = dbuffer; auto cmp = cbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), alpha); + auto alpha = _multiply(opacity, blender(cmp)); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), alpha); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } dbuffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; } // Up-Scaled } else { @@ -740,27 +821,28 @@ static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const Sw if ((uint32_t)sy >= image->h) continue; auto dst = dbuffer; auto cmp = cbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha); + auto alpha = _multiply(opacity, blender(cmp)); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), alpha); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } dbuffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; } } return true; } -static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint8_t (*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Scaled Masked Image"); - auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride + region.min.x); + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; // Down-Scaled if (image->scale < DOWN_SCALE_TOLERANCE) { @@ -769,14 +851,14 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag if (sy >= image->h) continue; auto dst = dbuffer; auto cmp = cbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), blender(cmp)); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } dbuffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; } // Up-Scaled } else { @@ -785,14 +867,14 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag if ((uint32_t)sy >= image->h) continue; auto dst = dbuffer; auto cmp = cbuffer; - for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { + for (auto x = region.min.x; x < region.max.x; ++x, ++dst, cmp += csize) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp)); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), blender(cmp)); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } dbuffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; } } return true; @@ -801,7 +883,7 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale) { - auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); // Down-Scaled if (image->scale < DOWN_SCALE_TOLERANCE) { @@ -812,7 +894,7 @@ static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale), opacity); + auto src = ALPHA_BLEND(_interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale), opacity); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -825,7 +907,7 @@ static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), opacity); + auto src = ALPHA_BLEND(_interpUpScaler(image->buf32, image->w, image->h, sx, sy), opacity); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -836,7 +918,7 @@ static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale) { - auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x); + auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x); // Down-Scaled if (image->scale < DOWN_SCALE_TOLERANCE) { @@ -847,7 +929,7 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { auto sx = (uint32_t)(x * itransform->e11 + itransform->e13); if (sx >= image->w) continue; - auto src = _interpDownScaler(image->data, image->stride, image->w, image->h, sx, sy, halfScale); + auto src = _interpDownScaler(image->buf32, image->stride, image->w, image->h, sx, sy, halfScale); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -860,7 +942,7 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { auto sx = x * itransform->e11 + itransform->e13; if ((uint32_t)sx >= image->w) continue; - auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy); + auto src = _interpUpScaler(image->buf32, image->w, image->h, sx, sy); *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); } } @@ -886,7 +968,7 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue); + return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.luma); } } else { if (surface->compositor->method == CompositeMethod::AlphaMask) { @@ -894,7 +976,7 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue); + return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.luma); } } } else { @@ -909,54 +991,56 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat /* Direct RGBA Image */ /************************************************************************/ -static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t (*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Direct Masked Image"); - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h2 = static_cast(region.max.y - region.min.y); auto w2 = static_cast(region.max.x - region.min.x); + auto csize = surface->compositor->image.channelSize; - auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer for (uint32_t y = 0; y < h2; ++y) { auto dst = buffer; auto cmp = cbuffer; auto src = sbuffer; - for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } buffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; sbuffer += image->stride; } return true; } -static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity, uint8_t (*blender)(uint8_t*)) { TVGLOG("SW_ENGINE", "Direct Masked Translucent Image"); - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h2 = static_cast(region.max.y - region.min.y); auto w2 = static_cast(region.max.x - region.min.x); + auto csize = surface->compositor->image.channelSize; - auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer for (uint32_t y = 0; y < h2; ++y) { auto dst = buffer; auto cmp = cbuffer; auto src = sbuffer; - for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) { - auto tmp = ALPHA_BLEND(*src, _multiplyAlpha(opacity, blendMethod(*cmp))); + for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, _multiply(opacity, blender(cmp))); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } buffer += surface->stride; - cbuffer += surface->compositor->image.stride; + cbuffer += surface->compositor->image.stride * csize; sbuffer += image->stride; } return true; @@ -965,8 +1049,8 @@ static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const Sw static bool _rasterDirectTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity) { - auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; - auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto dbuffer = &surface->buf32[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); for (auto y = region.min.y; y < region.max.y; ++y) { auto dst = dbuffer; @@ -984,8 +1068,8 @@ static bool _rasterDirectTranslucentRGBAImage(SwSurface* surface, const SwImage* static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region) { - auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; - auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); + auto dbuffer = &surface->buf32[region.min.y * surface->stride + region.min.x]; + auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); for (auto y = region.min.y; y < region.max.y; ++y) { auto dst = dbuffer; @@ -1010,7 +1094,7 @@ static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwB } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterDirectMaskedRGBAImage(surface, image, region, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.lumaValue); + return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.luma); } } else { if (surface->compositor->method == CompositeMethod::AlphaMask) { @@ -1018,7 +1102,7 @@ static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwB } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.lumaValue); + return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.luma); } } } else { @@ -1050,14 +1134,15 @@ static bool _rasterRGBAImage(SwSurface* surface, SwImage* image, const Matrix* t /* Rect Linear Gradient */ /************************************************************************/ -static bool _rasterLinearGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterLinearGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint8_t (*blender)(uint8_t*)) { if (fill->linear.len < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; auto sbuffer = static_cast(alloca(w * sizeof(uint32_t))); if (!sbuffer) return false; @@ -1067,12 +1152,12 @@ static bool _rasterLinearGradientMaskedRect(SwSurface* surface, const SwBBox& re auto dst = buffer; auto cmp = cbuffer; auto src = sbuffer; - for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp, ++src) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } buffer += surface->stride; - cbuffer += surface->stride; + cbuffer += surface->stride * csize; } return true; } @@ -1082,7 +1167,7 @@ static bool _rasterTranslucentLinearGradientRect(SwSurface* surface, const SwBBo { if (fill->linear.len < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); @@ -1105,7 +1190,7 @@ static bool _rasterSolidLinearGradientRect(SwSurface* surface, const SwBBox& reg { if (fill->linear.len < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); @@ -1124,7 +1209,7 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterLinearGradientMaskedRect(surface, region, fill, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.lumaValue); + return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.luma); } } else { if (fill->translucent) return _rasterTranslucentLinearGradientRect(surface, region, fill); @@ -1138,29 +1223,30 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, /* Rle Linear Gradient */ /************************************************************************/ -static bool _rasterLinearGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterLinearGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint8_t (*blender)(uint8_t*)) { if (fill->linear.len < FLT_EPSILON) return false; auto span = rle->spans; - auto cbuffer = surface->compositor->image.data; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; auto buffer = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!buffer) return false; for (uint32_t i = 0; i < rle->size; ++i, ++span) { fillFetchLinear(fill, buffer, span->y, span->x, span->len); - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; auto src = buffer; if (span->coverage == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { auto ialpha = 255 - span->coverage; - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); tmp = ALPHA_BLEND(tmp, span->coverage) + ALPHA_BLEND(*dst, ialpha); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } @@ -1179,7 +1265,7 @@ static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleD if (!buffer) return false; for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; fillFetchLinear(fill, buffer, span->y, span->x, span->len); if (span->coverage == 255) { for (uint32_t x = 0; x < span->len; ++x, ++dst) { @@ -1207,10 +1293,10 @@ static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* r for (uint32_t i = 0; i < rle->size; ++i, ++span) { if (span->coverage == 255) { - fillFetchLinear(fill, surface->buffer + span->y * surface->stride + span->x, span->y, span->x, span->len); + fillFetchLinear(fill, surface->buf32 + span->y * surface->stride + span->x, span->y, span->x, span->len); } else { fillFetchLinear(fill, buf, span->y, span->x, span->len); - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; for (uint32_t x = 0; x < span->len; ++x) { dst[x] = INTERPOLATE(span->coverage, buf[x], dst[x]); } @@ -1230,7 +1316,7 @@ static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, c } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterLinearGradientMaskedRle(surface, rle, fill, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue); + return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.luma); } } else { if (fill->translucent) return _rasterTranslucentLinearGradientRle(surface, rle, fill); @@ -1244,14 +1330,15 @@ static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, c /* Rect Radial Gradient */ /************************************************************************/ -static bool _rasterRadialGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterRadialGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, uint8_t(*blender)(uint8_t*)) { if (fill->radial.a < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); - auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; auto sbuffer = static_cast(alloca(w * sizeof(uint32_t))); if (!sbuffer) return false; @@ -1261,12 +1348,12 @@ static bool _rasterRadialGradientMaskedRect(SwSurface* surface, const SwBBox& re auto dst = buffer; auto cmp = cbuffer; auto src = sbuffer; - for (uint32_t x = 0; x < w; ++x, ++dst, ++cmp, ++src) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } buffer += surface->stride; - cbuffer += surface->stride; + cbuffer += surface->stride * csize; } return true; } @@ -1276,7 +1363,7 @@ static bool _rasterTranslucentRadialGradientRect(SwSurface* surface, const SwBBo { if (fill->radial.a < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); @@ -1299,7 +1386,7 @@ static bool _rasterSolidRadialGradientRect(SwSurface* surface, const SwBBox& reg { if (fill->radial.a < FLT_EPSILON) return false; - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); @@ -1319,7 +1406,7 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterRadialGradientMaskedRect(surface, region, fill, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.lumaValue); + return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.luma); } } else { if (fill->translucent) return _rasterTranslucentRadialGradientRect(surface, region, fill); @@ -1333,28 +1420,29 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, /* RLE Radial Gradient */ /************************************************************************/ -static bool _rasterRadialGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterRadialGradientMaskedRle(SwSurface* surface, const SwRleData* rle, const SwFill* fill, uint8_t(*blender)(uint8_t*)) { if (fill->radial.a < FLT_EPSILON) return false; auto span = rle->spans; - auto cbuffer = surface->compositor->image.data; + auto csize = surface->compositor->image.channelSize; + auto cbuffer = surface->compositor->image.buf8; auto buffer = static_cast(alloca(surface->w * sizeof(uint32_t))); if (!buffer) return false; for (uint32_t i = 0; i < rle->size; ++i, ++span) { fillFetchRadial(fill, buffer, span->y, span->x, span->len); - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; auto src = buffer; if (span->coverage == 255) { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { - auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src, cmp += csize) { + auto tmp = ALPHA_BLEND(*src, blender(cmp)); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } else { - for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) { - auto tmp = INTERPOLATE(span->coverage, ALPHA_BLEND(*src, blendMethod(*cmp)), *dst); + for (uint32_t x = 0; x < span->len; ++x, ++dst, ++src, cmp += csize) { + auto tmp = INTERPOLATE(span->coverage, ALPHA_BLEND(*src, blender(cmp)), *dst); *dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp)); } } @@ -1372,7 +1460,7 @@ static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleD if (!buffer) return false; for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; fillFetchRadial(fill, buffer, span->y, span->x, span->len); if (span->coverage == 255) { for (uint32_t x = 0; x < span->len; ++x, ++dst) { @@ -1399,7 +1487,7 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r auto span = rle->spans; for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; if (span->coverage == 255) { fillFetchRadial(fill, dst, span->y, span->x, span->len); } else { @@ -1424,7 +1512,7 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { return _rasterRadialGradientMaskedRle(surface, rle, fill, _ialpha); } else if (surface->compositor->method == CompositeMethod::LumaMask) { - return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue); + return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.luma); } } else { if (fill->translucent) _rasterTranslucentRadialGradientRle(surface, rle, fill); @@ -1433,7 +1521,6 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c return false; } - /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -1445,7 +1532,7 @@ void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) #elif defined(THORVG_NEON_VECTOR_SUPPORT) neonRasterRGBA32(dst, val, offset, len); #else - cRasterRGBA32(dst, val, offset, len); + cRasterPixels(dst, val, offset, len); #endif } @@ -1454,27 +1541,41 @@ bool rasterCompositor(SwSurface* surface) { if (surface->cs == ColorSpace::ABGR8888 || surface->cs == ColorSpace::ABGR8888S) { surface->blender.join = _abgrJoin; - surface->blender.lumaValue = _abgrLumaValue; + surface->blender.luma = _abgrLuma; } else if (surface->cs == ColorSpace::ARGB8888 || surface->cs == ColorSpace::ARGB8888S) { surface->blender.join = _argbJoin; - surface->blender.lumaValue = _argbLumaValue; + surface->blender.luma = _argbLuma; } else { - //What Color Space ??? + TVGERR("SW_ENGINE", "Unsupported Colorspace(%d) is expected!", surface->cs); return false; } return true; } -bool rasterClear(SwSurface* surface) +bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h) { - if (!surface || !surface->buffer || surface->stride <= 0 || surface->w <= 0 || surface->h <= 0) return false; + if (!surface || !surface->buf32 || surface->stride == 0 || surface->w == 0 || surface->h == 0) return false; - if (surface->w == surface->stride) { - rasterRGBA32(surface->buffer, 0x00000000, 0, surface->w * surface->h); - } else { - for (uint32_t i = 0; i < surface->h; i++) { - rasterRGBA32(surface->buffer + surface->stride * i, 0x00000000, 0, surface->w); + //full clear + if (surface->channelSize == sizeof(uint32_t)) { + if (w == surface->stride) { + rasterRGBA32(surface->buf32 + (surface->stride * y), 0x00000000, 0, w * h); + } else { + auto buffer = surface->buf32 + (surface->stride * y + x); + for (uint32_t i = 0; i < h; i++) { + rasterRGBA32(buffer + (surface->stride * i), 0x00000000, 0, w); + } + } + //partial clear + } else if (surface->channelSize == sizeof(uint8_t)) { + if (w == surface->stride) { + _rasterGrayscale8(surface->buf8 + (surface->stride * y), 0x00, 0, w * h); + } else { + auto buffer = surface->buf8 + (surface->stride * y + x); + for (uint32_t i = 0; i < h; i++) { + _rasterGrayscale8(buffer + (surface->stride * i), 0x00, 0, w); + } } } return true; @@ -1483,11 +1584,13 @@ bool rasterClear(SwSurface* surface) void rasterUnpremultiply(Surface* surface) { + if (surface->channelSize != sizeof(uint32_t)) return; + TVGLOG("SW_ENGINE", "Unpremultiply [Size: %d x %d]", surface->w, surface->h); //OPTIMIZE_ME: +SIMD for (uint32_t y = 0; y < surface->h; y++) { - auto buffer = surface->buffer + surface->stride * y; + auto buffer = surface->buf32 + surface->stride * y; for (uint32_t x = 0; x < surface->w; ++x) { uint8_t a = buffer[x] >> 24; if (a == 255) { @@ -1511,10 +1614,12 @@ void rasterUnpremultiply(Surface* surface) void rasterPremultiply(Surface* surface) { + if (surface->channelSize != sizeof(uint32_t)) return; + TVGLOG("SW_ENGINE", "Premultiply [Size: %d x %d]", surface->w, surface->h); //OPTIMIZE_ME: +SIMD - auto buffer = surface->buffer; + auto buffer = surface->buf32; for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride) { auto dst = buffer; for (uint32_t x = 0; x < surface->w; ++x, ++dst) { @@ -1529,6 +1634,11 @@ void rasterPremultiply(Surface* surface) bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) { + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale gradient!"); + return false; + } + if (!shape->fill) return false; if (shape->fastTrack) { @@ -1544,6 +1654,11 @@ bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id) bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id) { + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale gradient!"); + return false; + } + if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false; if (id == TVG_CLASS_ID_LINEAR) return _rasterLinearGradientRle(surface, shape->strokeRle, shape->stroke->fill); @@ -1556,34 +1671,35 @@ bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id) bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (a < 255) { - r = _multiplyAlpha(r, a); - g = _multiplyAlpha(g, a); - b = _multiplyAlpha(b, a); + r = _multiply(r, a); + g = _multiply(g, a); + b = _multiply(b, a); } - auto color = surface->blender.join(r, g, b, a); - - if (shape->fastTrack) return _rasterRect(surface, shape->bbox, color, a); - else return _rasterRle(surface, shape->rle, color, a); + if (shape->fastTrack) return _rasterRect(surface, shape->bbox, r, g, b, a); + else return _rasterRle(surface, shape->rle, r, g, b, a); } bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { if (a < 255) { - r = _multiplyAlpha(r, a); - g = _multiplyAlpha(g, a); - b = _multiplyAlpha(b, a); + r = _multiply(r, a); + g = _multiply(g, a); + b = _multiply(b, a); } - auto color = surface->blender.join(r, g, b, a); - - return _rasterRle(surface, shape->strokeRle, color, a); + return _rasterRle(surface, shape->strokeRle, r, g, b, a); } bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint32_t opacity) { + if (surface->channelSize == sizeof(uint8_t)) { + TVGERR("SW_ENGINE", "Not supported grayscale image!"); + return false; + } + //Verify Boundary if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast(surface->w) || bbox.min.y >= static_cast(surface->h)) return false; diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h index b5a2a3c72..cf658a6ab 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h @@ -82,9 +82,15 @@ static void avxRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_ } -static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->blender.join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); @@ -125,13 +131,19 @@ static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, u } -static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +static bool avxRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->blender.join(r, g, b, a); auto span = rle->spans; uint32_t src; for (uint32_t i = 0; i < rle->size; ++i) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); else src = color; diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterC.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterC.h index fb19b1ee9..18a096648 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterC.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterC.h @@ -20,43 +20,70 @@ * SOFTWARE. */ -static void inline cRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len) +template +static void inline cRasterPixels(PIXEL_T* dst, uint32_t val, uint32_t offset, int32_t len) { dst += offset; while (len--) *dst++ = val; } -static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { auto span = rle->spans; - uint32_t src; - for (uint32_t i = 0; i < rle->size; ++i, ++span) { - auto dst = &surface->buffer[span->y * surface->stride + span->x]; - - if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); - else src = color; - - for (uint32_t x = 0; x < span->len; ++x, ++dst) { - *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + //32bit channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, a); + uint32_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf32[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); + else src = color; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + ALPHA_BLEND(*dst, _ialpha(src)); + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + uint8_t src; + for (uint32_t i = 0; i < rle->size; ++i, ++span) { + auto dst = &surface->buf8[span->y * surface->stride + span->x]; + if (span->coverage < 255) src = _multiply(span->coverage, a); + else src = a; + for (uint32_t x = 0; x < span->len; ++x, ++dst) { + *dst = src + _multiply(*dst, ~src); + } } } return true; } -static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); - auto ialpha = _ialpha(color); - for (uint32_t y = 0; y < h; ++y) { - auto dst = &buffer[y * surface->stride]; - for (uint32_t x = 0; x < w; ++x, ++dst) { - *dst = color + ALPHA_BLEND(*dst, ialpha); + //32bits channels + if (surface->channelSize == sizeof(uint32_t)) { + auto color = surface->blender.join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; + auto ialpha = _ialpha(color); + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = color + ALPHA_BLEND(*dst, ialpha); + } + } + //8bit grayscale + } else if (surface->channelSize == sizeof(uint8_t)) { + auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; + for (uint32_t y = 0; y < h; ++y) { + auto dst = &buffer[y * surface->stride]; + for (uint32_t x = 0; x < w; ++x, ++dst) { + *dst = a + _multiply(*dst, ~a); + } } } return true; @@ -67,7 +94,7 @@ static bool inline cRasterABGRtoARGB(Surface* surface) { TVGLOG("SW_ENGINE", "Convert ColorSpace ABGR - ARGB [Size: %d x %d]", surface->w, surface->h); - auto buffer = surface->buffer; + auto buffer = surface->buf32; for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride) { auto dst = buffer; for (uint32_t x = 0; x < surface->w; ++x, ++dst) { diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h index 0935f4057..5bed2f85a 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h @@ -49,8 +49,14 @@ static void neonRasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32 } -static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint32_t color) +static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->blender.join(r, g, b, a); auto span = rle->spans; uint32_t src; uint8x8_t *vDst = nullptr; @@ -60,7 +66,7 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); else src = color; - auto dst = &surface->buffer[span->y * surface->stride + span->x]; + auto dst = &surface->buf32[span->y * surface->stride + span->x]; auto ialpha = 255 - _alpha(src); if ((((size_t) dst) & 0x7) != 0) { @@ -88,9 +94,15 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRleData* rle, u } -static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint32_t color) +static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; + if (surface->channelSize != sizeof(uint32_t)) { + TVGERR("SW_ENGINE", "Unsupported Channel Size = %d", surface->channelSize); + return false; + } + + auto color = surface->blender.join(r, g, b, a); + auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); auto ialpha = 255 - _alpha(color); diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h index dec7395b2..52585162f 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h @@ -69,7 +69,7 @@ static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, in } -static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t opacity, uint8_t(*blender)(uint8_t*), AASpans* aaSpans) { #define TEXMAP_TRANSLUCENT #define TEXMAP_MASKING @@ -79,7 +79,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, } -static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, uint8_t(*blender)(uint8_t*), AASpans* aaSpans) { #define TEXMAP_MASKING #include "tvgSwRasterTexmapInternal.h" @@ -102,7 +102,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, /* This mapping algorithm is based on Mikael Kalms's. */ -static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint32_t (*blendMethod)(uint32_t), AASpans* aaSpans) +static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, uint32_t opacity, Polygon& polygon, uint8_t(*blender)(uint8_t*), AASpans* aaSpans) { float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x}; float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y}; @@ -190,9 +190,9 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const dxdyb = dxdy[0]; xb = x[0] + dy * dxdyb + (off_y * dxdyb); - if (blendMethod) { - if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blendMethod, aaSpans); - else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blendMethod, aaSpans); + if (blender) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blender, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blender, aaSpans); } else { if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans); else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans); @@ -211,9 +211,9 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const // Set right edge X-slope and perform subpixel pre-stepping dxdyb = dxdy[2]; xb = x[1] + (1 - (y[1] - yi[1])) * dxdyb + (off_y * dxdyb); - if (blendMethod) { - if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blendMethod, aaSpans); - else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blendMethod, aaSpans); + if (blender) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blender, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blender, aaSpans); } else { if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans); else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans); @@ -240,9 +240,9 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const ua = u[0] + dy * dudya + (off_y * dudya); va = v[0] + dy * dvdya + (off_y * dvdya); - if (blendMethod) { - if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blendMethod, aaSpans); - else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blendMethod, aaSpans); + if (blender) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], blender, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, blender, aaSpans); } else { if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], aaSpans); else _rasterPolygonImageSegment(surface, image, region, yi[0], yi[1], opacity, aaSpans); @@ -264,9 +264,9 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const ua = u[1] + dy * dudya + (off_y * dudya); va = v[1] + dy * dvdya + (off_y * dvdya); - if (blendMethod) { - if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blendMethod, aaSpans); - else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blendMethod, aaSpans); + if (blender) { + if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], blender, aaSpans); + else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, blender, aaSpans); } else { if (opacity == 255) _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], aaSpans); else _rasterPolygonImageSegment(surface, image, region, yi[1], yi[2], opacity, aaSpans); @@ -502,7 +502,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) auto offset = y * surface->stride; //Left edge - dst = surface->buffer + (offset + line->x[0]); + dst = surface->buf32 + (offset + line->x[0]); if (line->x[0] > 1) pixel = *(dst - 1); else pixel = *dst; @@ -514,7 +514,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) } //Right edge - dst = surface->buffer + (offset + line->x[1] - 1); + dst = surface->buf32 + (offset + line->x[1] - 1); if (line->x[1] < (int32_t)(surface->w - 1)) pixel = *(dst + 1); else pixel = *dst; @@ -545,7 +545,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans) | / | 3 -- 2 */ -static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint8_t(*blender)(uint8_t*)) { //Exceptions: No dedicated drawing area? if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; @@ -576,14 +576,14 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const polygon.vertex[1] = vertices[1]; polygon.vertex[2] = vertices[3]; - _rasterPolygonImage(surface, image, region, opacity, polygon, blendMethod, aaSpans); + _rasterPolygonImage(surface, image, region, opacity, polygon, blender, aaSpans); //Draw the second polygon polygon.vertex[0] = vertices[1]; polygon.vertex[1] = vertices[2]; polygon.vertex[2] = vertices[3]; - _rasterPolygonImage(surface, image, region, opacity, polygon, blendMethod, aaSpans); + _rasterPolygonImage(surface, image, region, opacity, polygon, blender, aaSpans); return _apply(surface, aaSpans); } @@ -602,7 +602,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Should provide two Polygons, one for each triangle. // TODO: region? */ -static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) +static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint8_t(*blender)(uint8_t*)) { //Exceptions: No dedicated drawing area? if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; @@ -636,7 +636,7 @@ static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, c auto aaSpans = _AASpans(ys, ye, image, region); if (aaSpans) { for (uint32_t i = 0; i < mesh->triangleCnt; i++) { - _rasterPolygonImage(surface, image, region, opacity, transformedTris[i], blendMethod, aaSpans); + _rasterPolygonImage(surface, image, region, opacity, transformedTris[i], blender, aaSpans); } // Apply to surface (note: frees the AA spans) _apply(surface, aaSpans); diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h index 8fc0f5b74..51685fe6e 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h @@ -24,8 +24,8 @@ float _dudx = dudx, _dvdx = dvdx; float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya; float _xa = xa, _xb = xb, _ua = ua, _va = va; - auto sbuf = image->data; - auto dbuf = surface->buffer; + auto sbuf = image->buf32; + auto dbuf = surface->buf32; int32_t sw = static_cast(image->stride); int32_t sh = image->h; int32_t dw = surface->stride; @@ -37,7 +37,8 @@ SwSpan* span = nullptr; //used only when rle based. #ifdef TEXMAP_MASKING - uint32_t* cmp; + uint8_t* cmp; + auto csize = surface->compositor->image.channelSize; #endif if (!_arrange(image, region, yStart, yEnd)) return; @@ -94,7 +95,7 @@ x = x1; #ifdef TEXMAP_MASKING - cmp = &surface->compositor->image.data[y * surface->compositor->image.stride + x1]; + cmp = &surface->compositor->image.buf8[(y * surface->compositor->image.stride + x1) * csize]; #endif //Draw horizontal line while (x++ < x2) { @@ -130,9 +131,9 @@ px = INTERPOLATE(ab, px, px2); } #if defined(TEXMAP_MASKING) && defined(TEXMAP_TRANSLUCENT) - auto src = ALPHA_BLEND(px, _multiplyAlpha(opacity, blendMethod(*cmp))); + auto src = ALPHA_BLEND(px, _multiply(opacity, blender(cmp))); #elif defined(TEXMAP_MASKING) - auto src = ALPHA_BLEND(px, blendMethod(*cmp)); + auto src = ALPHA_BLEND(px, blender(cmp)); #elif defined(TEXMAP_TRANSLUCENT) auto src = ALPHA_BLEND(px, opacity); #else @@ -141,7 +142,7 @@ *buf = src + ALPHA_BLEND(*buf, _ialpha(src)); ++buf; #ifdef TEXMAP_MASKING - ++cmp; + cmp += csize; #endif //Step UV horizontally u += _dudx; diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp index bc35ebb8f..6223bc872 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp @@ -173,8 +173,6 @@ struct SwShapeTask : SwTask //Clip Path for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { auto clipper = static_cast(*clip); - //Guarantee composition targets get ready. - clipper->done(tid); //Clip shape rle if (shape.rle && !clipper->clip(shape.rle)) goto err; //Clip stroke rle @@ -225,25 +223,17 @@ struct SwSceneTask : SwTask if (!sceneRle) sceneRle = static_cast(calloc(1, sizeof(SwRleData))); else rleReset(sceneRle); - //Only one shape - if (scene.count == 1) { - auto clipper = static_cast(*scene.data); - clipper->done(tid); //Merge shapes if it has more than one shapes - } else { + if (scene.count > 1) { //Merge first two clippers auto clipper1 = static_cast(*scene.data); - clipper1->done(tid); - auto clipper2 = static_cast(*(scene.data + 1)); - clipper2->done(tid); rleMerge(sceneRle, clipper1->rle(), clipper2->rle()); //Unify the remained clippers for (auto rd = scene.data + 2; rd < (scene.data + scene.count); ++rd) { auto clipper = static_cast(*rd); - clipper->done(tid); rleMerge(sceneRle, sceneRle, clipper->rle()); } } @@ -285,10 +275,11 @@ struct SwImageTask : SwTask if (!source->premultiplied) rasterPremultiply(source); } - image.data = source->buffer; + image.data = source->data; image.w = source->w; image.h = source->h; image.stride = source->stride; + image.channelSize = source->channelSize; //Invisible shape turned to visible by alpha. if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) { @@ -305,8 +296,6 @@ struct SwImageTask : SwTask imageDelOutline(&image, mpool, tid); for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { auto clipper = static_cast(*clip); - //Guarantee composition targets get ready. - clipper->done(tid); if (!clipper->clip(image.rle)) goto err; } return; @@ -423,17 +412,18 @@ bool SwRenderer::viewport(const RenderRegion& vp) } -bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs) +bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs) { - if (!buffer || stride == 0 || w == 0 || h == 0 || w > stride) return false; + if (!data || stride == 0 || w == 0 || h == 0 || w > stride) return false; if (!surface) surface = new SwSurface; - surface->buffer = buffer; + surface->data = data; surface->stride = stride; surface->w = w; surface->h = h; surface->cs = cs; + surface->channelSize = CHANNEL_SIZE(cs); surface->premultiplied = true; surface->owner = true; @@ -447,9 +437,10 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t bool SwRenderer::preRender() { - return rasterClear(surface); + return rasterClear(surface, 0, 0, surface->w, surface->h); } + void SwRenderer::clearCompositors() { //Free Composite Caches @@ -505,7 +496,7 @@ bool SwRenderer::renderShape(RenderData data) //Do Stroking Composition if (task->cmpStroking) { opacity = 255; - cmp = target(task->bounds()); + cmp = target(task->bounds(), colorSpace()); beginComposite(cmp, CompositeMethod::None, task->opacity); //No Stroking Composition } else { @@ -571,7 +562,7 @@ bool SwRenderer::mempool(bool shared) } -Compositor* SwRenderer::target(const RenderRegion& region) +Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) { auto x = region.x; auto y = region.y; @@ -581,13 +572,15 @@ Compositor* SwRenderer::target(const RenderRegion& region) auto sh = static_cast(surface->h); //Out of boundary - if (x > sw || y > sh) return nullptr; + if (x >= sw || y >= sh || x + w < 0 || y + h < 0) return nullptr; SwSurface* cmp = nullptr; + auto reqChannelSize = CHANNEL_SIZE(cs); + //Use cached data for (auto p = compositors.data; p < (compositors.data + compositors.count); ++p) { - if ((*p)->compositor->valid) { + if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) { cmp = *p; break; } @@ -596,17 +589,16 @@ Compositor* SwRenderer::target(const RenderRegion& region) //New Composition if (!cmp) { cmp = new SwSurface; - if (!cmp) goto err; //Inherits attributes from main surface *cmp = *surface; cmp->compositor = new SwCompositor; - if (!cmp->compositor) goto err; - //SwImage, Optimize Me: Surface size from MainSurface(WxH) to Parameter W x H - cmp->compositor->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->stride * surface->h); - if (!cmp->compositor->image.data) goto err; + //TODO: We can optimize compositor surface size from (surface->stride x surface->h) to Parameter(w x h) + cmp->compositor->image.data = (pixel_t*)malloc(reqChannelSize * surface->stride * surface->h); + cmp->channelSize = cmp->compositor->image.channelSize = reqChannelSize; + compositors.push(cmp); } @@ -628,30 +620,16 @@ Compositor* SwRenderer::target(const RenderRegion& region) cmp->compositor->image.h = surface->h; cmp->compositor->image.direct = true; - //We know partial clear region - cmp->buffer = cmp->compositor->image.data + (cmp->stride * y + x); - cmp->w = w; - cmp->h = h; - - rasterClear(cmp); - - //Recover context - cmp->buffer = cmp->compositor->image.data; + cmp->data = cmp->compositor->image.data; cmp->w = cmp->compositor->image.w; cmp->h = cmp->compositor->image.h; + rasterClear(cmp, x, y, w, h); + //Switch render target surface = cmp; return cmp->compositor; - -err: - if (cmp) { - if (cmp->compositor) delete(cmp->compositor); - delete(cmp); - } - - return nullptr; } @@ -675,6 +653,13 @@ bool SwRenderer::endComposite(Compositor* cmp) } +ColorSpace SwRenderer::colorSpace() +{ + if (surface) return surface->cs; + else return ColorSpace::Unsupported; +} + + bool SwRenderer::dispose(RenderData data) { auto task = static_cast(data); @@ -697,6 +682,13 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, //Finish previous task if it has duplicated request. task->done(); + //TODO: Failed threading them. It would be better if it's possible. + //See: https://github.com/thorvg/thorvg/issues/1409 + //Guarantee composition targets get ready. + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + static_cast(*clip)->done(); + } + task->clips = clips; if (transform) { @@ -747,6 +739,12 @@ RenderData SwRenderer::prepare(const Array& scene, RenderData data, if (!task) task = new SwSceneTask; task->scene = scene; + //TODO: Failed threading them. It would be better if it's possible. + //See: https://github.com/thorvg/thorvg/issues/1409 + //Guarantee composition targets get ready. + for (auto task = scene.data; task < (scene.data + scene.count); ++task) { + static_cast(*task)->done(); + } return prepareCommon(task, transform, opacity, clips, flags); } diff --git a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.h b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.h index e8847598f..36614fa1c 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/sw_engine/tvgSwRenderer.h @@ -47,13 +47,14 @@ class SwRenderer : public RenderMethod RenderRegion region(RenderData data) override; RenderRegion viewport() override; bool viewport(const RenderRegion& vp) override; + ColorSpace colorSpace() override; bool clear() override; bool sync() override; - bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs); + bool target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs); bool mempool(bool shared); - Compositor* target(const RenderRegion& region) override; + Compositor* target(const RenderRegion& region, ColorSpace cs) override; bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override; bool endComposite(Compositor* cmp) override; void clearCompositors(); diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgPaint.cpp b/libfenrir/src/main/jni/thorvg/src/lib/tvgPaint.cpp index 029c6b46c..5746fe49a 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgPaint.cpp +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgPaint.cpp @@ -167,9 +167,10 @@ bool Paint::Impl::render(RenderMethod& renderer) if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) { auto region = smethod->bounds(renderer); if (region.w == 0 || region.h == 0) return true; - cmp = renderer.target(region); - renderer.beginComposite(cmp, CompositeMethod::None, 255); - compData->target->pImpl->render(renderer); + cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method)); + if (renderer.beginComposite(cmp, CompositeMethod::None, 255)) { + compData->target->pImpl->render(renderer); + } } if (cmp) renderer.beginComposite(cmp, compData->method, compData->target->pImpl->opacity); @@ -347,12 +348,6 @@ Matrix Paint::transform() noexcept } -TVG_DEPRECATED Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept -{ - return this->bounds(x, y, w, h, false); -} - - Result Paint::bounds(float* x, float* y, float* w, float* h, bool transform) const noexcept { if (pImpl->bounds(x, y, w, h, transform)) return Result::Success; diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgPicture.cpp b/libfenrir/src/main/jni/thorvg/src/lib/tvgPicture.cpp index 897f7849c..95ae14b84 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgPicture.cpp +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgPicture.cpp @@ -26,7 +26,7 @@ /* External Class Implementation */ /************************************************************************/ -Picture::Picture() : pImpl(new Impl) +Picture::Picture() : pImpl(new Impl(this)) { Paint::pImpl->id = TVG_CLASS_ID_PICTURE; Paint::pImpl->method(new PaintMethod(pImpl)); @@ -67,12 +67,6 @@ Result Picture::load(const char* data, uint32_t size, const string& mimeType, bo } -TVG_DEPRECATED Result Picture::load(const char* data, uint32_t size, bool copy) noexcept -{ - return load(data, size, "", copy); -} - - Result Picture::load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept { if (!data || w <= 0 || h <= 0) return Result::InvalidArguments; @@ -116,7 +110,7 @@ const uint32_t* Picture::data(uint32_t* w, uint32_t* h) const noexcept if (w) *w = 0; if (h) *h = 0; } - if (pImpl->surface) return pImpl->surface->buffer; + if (pImpl->surface) return pImpl->surface->buf32; else return nullptr; } diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgPictureImpl.h b/libfenrir/src/main/jni/thorvg/src/lib/tvgPictureImpl.h index b4d28e707..1caf3a4c8 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgPictureImpl.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgPictureImpl.h @@ -67,7 +67,13 @@ struct Picture::Impl RenderData rd = nullptr; //engine data float w = 0, h = 0; RenderMesh rm; //mesh data + Picture* picture = nullptr; bool resizing = false; + bool needComp = false; //need composition + + Impl(Picture* p) : picture(p) + { + } ~Impl() { @@ -127,6 +133,19 @@ struct Picture::Impl else return RenderTransform(pTransform, &tmp); } + bool needComposition(uint32_t opacity) + { + //In this case, paint(scene) would try composition itself. + if (opacity < 255) return false; + + //Composition test + const Paint* target; + auto method = picture->composite(&target); + if (!target || method == tvg::CompositeMethod::ClipPath) return false; + if (target->pImpl->opacity < 255 && target->pImpl->opacity > 0) return true; + return false; + } + RenderData update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array& clips, RenderUpdateFlag pFlag, bool clipper) { auto flag = load(); @@ -139,6 +158,7 @@ struct Picture::Impl loader->resize(paint, w, h); resizing = false; } + needComp = needComposition(opacity) ? true : false; rd = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast(pFlag | flag), clipper); } return rd; @@ -146,9 +166,18 @@ struct Picture::Impl bool render(RenderMethod &renderer) { + bool ret = false; if (surface) return renderer.renderImage(rd); - else if (paint) return paint->pImpl->render(renderer); - return false; + else if (paint) { + Compositor* cmp = nullptr; + if (needComp) { + cmp = renderer.target(bounds(renderer), renderer.colorSpace()); + renderer.beginComposite(cmp, CompositeMethod::None, 255); + } + ret = paint->pImpl->render(renderer); + if (cmp) renderer.endComposite(cmp); + } + return ret; } bool viewbox(float* x, float* y, float* w, float* h) @@ -245,7 +274,7 @@ struct Picture::Impl if (paint || surface) return Result::InsufficientCondition; if (loader) loader->close(); loader = LoaderMgr::loader(data, w, h, copy); - if (!loader) return Result::NonSupport; + if (!loader) return Result::FailedAllocation; this->w = loader->w; this->h = loader->h; return Result::Success; diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgRender.h b/libfenrir/src/main/jni/thorvg/src/lib/tvgRender.h index 8f9e7ce02..6270fa531 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgRender.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgRender.h @@ -30,6 +30,7 @@ namespace tvg { using RenderData = void*; +using pixel_t = uint32_t; enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, GradientStroke = 64, All = 255}; @@ -41,15 +42,21 @@ enum ColorSpace ARGB8888, //The channels are joined in the order: alpha, red, green, blue. Colors are alpha-premultiplied. ABGR8888S, //The channels are joined in the order: alpha, blue, green, red. Colors are un-alpha-premultiplied. ARGB8888S, //The channels are joined in the order: alpha, red, green, blue. Colors are un-alpha-premultiplied. + Grayscale8, //One single channel data. Unsupported //TODO: Change to the default, At the moment, we put it in the last to align with SwCanvas::Colorspace. }; struct Surface { - uint32_t* buffer; + union { + pixel_t* data; //system based data pointer + uint32_t* buf32; //for explicit 32bits channels + uint8_t* buf8; //for explicit 8bits grayscale + }; uint32_t stride; uint32_t w, h; ColorSpace cs; + uint8_t channelSize; bool premultiplied; //Alpha-premultiplied bool owner; //Only owner could modify the buffer @@ -221,15 +228,47 @@ class RenderMethod virtual RenderRegion region(RenderData data) = 0; virtual RenderRegion viewport() = 0; virtual bool viewport(const RenderRegion& vp) = 0; + virtual ColorSpace colorSpace() = 0; virtual bool clear() = 0; virtual bool sync() = 0; - virtual Compositor* target(const RenderRegion& region) = 0; + virtual Compositor* target(const RenderRegion& region, ColorSpace cs) = 0; virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0; virtual bool endComposite(Compositor* cmp) = 0; }; +static inline uint8_t CHANNEL_SIZE(ColorSpace cs) +{ + switch(cs) { + case ColorSpace::ABGR8888: + case ColorSpace::ABGR8888S: + case ColorSpace::ARGB8888: + case ColorSpace::ARGB8888S: + return sizeof(uint32_t); + case ColorSpace::Grayscale8: + return sizeof(uint8_t); + case ColorSpace::Unsupported: + default: + TVGERR("SW_ENGINE", "Unsupported Channel Size! = %d", (int)cs); + return 0; + } +} + +static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, CompositeMethod method) +{ + switch(method) { + case CompositeMethod::AlphaMask: + case CompositeMethod::InvAlphaMask: + return ColorSpace::Grayscale8; + case CompositeMethod::LumaMask: + return renderer.colorSpace(); + default: + TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method); + return ColorSpace::Unsupported; + } +} + } #endif //_TVG_RENDER_H_ diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgSceneImpl.h b/libfenrir/src/main/jni/thorvg/src/lib/tvgSceneImpl.h index 5766b9e75..3f5945391 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgSceneImpl.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgSceneImpl.h @@ -59,10 +59,10 @@ struct SceneIterator : Iterator struct Scene::Impl { Array paints; - uint8_t opacity; //for composition RenderMethod* renderer = nullptr; //keep it for explicit clear RenderData rd = nullptr; Scene* scene = nullptr; + uint8_t opacity; //for composition Impl(Scene* s) : scene(s) { @@ -100,9 +100,11 @@ struct Scene::Impl if (opacity == 255) return false; //If scene has several children or only scene, it may require composition. - if (paints.count > 1) return true; - if (paints.count == 1 && (*paints.data)->identifier() == TVG_CLASS_ID_SCENE) return true; - return false; + //OPTIMIZE: the bitmap type of the picture would not need the composition. + //OPTIMIZE: a single paint of a scene would not need the composition. + if (paints.count == 1 && (*paints.data)->identifier() == TVG_CLASS_ID_SHAPE) return false; + + return true; } RenderData update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flag, bool clipper) @@ -135,7 +137,7 @@ struct Scene::Impl Compositor* cmp = nullptr; if (needComposition(opacity)) { - cmp = renderer.target(bounds(renderer)); + cmp = renderer.target(bounds(renderer), renderer.colorSpace()); renderer.beginComposite(cmp, CompositeMethod::None, opacity); } diff --git a/libfenrir/src/main/jni/thorvg/src/lib/tvgTaskScheduler.h b/libfenrir/src/main/jni/thorvg/src/lib/tvgTaskScheduler.h index a3954c6dd..0c6770d3e 100644 --- a/libfenrir/src/main/jni/thorvg/src/lib/tvgTaskScheduler.h +++ b/libfenrir/src/main/jni/thorvg/src/lib/tvgTaskScheduler.h @@ -51,7 +51,7 @@ struct Task public: virtual ~Task() = default; - void done(unsigned tid = 0) + void done() { if (!pending) return; diff --git a/libfenrir/src/main/jni/thorvg/src/loaders/raw/tvgRawLoader.cpp b/libfenrir/src/main/jni/thorvg/src/loaders/raw/tvgRawLoader.cpp index d81de06c7..5f5e72b0d 100644 --- a/libfenrir/src/main/jni/thorvg/src/loaders/raw/tvgRawLoader.cpp +++ b/libfenrir/src/main/jni/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -82,11 +82,12 @@ unique_ptr RawLoader::bitmap() //TODO: It's better to keep this surface instance in the loader side auto surface = new Surface; - surface->buffer = content; + surface->buf32 = content; surface->stride = static_cast(w); surface->w = static_cast(w); surface->h = static_cast(h); surface->cs = cs; + surface->channelSize = sizeof(uint32_t); surface->premultiplied = true; surface->owner = true; diff --git a/libfenrir/src/main/jni/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/libfenrir/src/main/jni/thorvg/src/loaders/svg/tvgSvgLoader.cpp index 3b1dc9e97..8f3d04e2d 100644 --- a/libfenrir/src/main/jni/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/libfenrir/src/main/jni/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -1906,6 +1906,7 @@ static SvgNode* _getDefsNode(SvgNode* node) } if (node->type == SvgNodeType::Doc) return node->node.doc.defs; + if (node->type == SvgNodeType::Defs) return node; return nullptr; } @@ -2937,6 +2938,16 @@ static void _copyAttr(SvgNode* to, const SvgNode* from) } break; } + case SvgNodeType::Use: { + to->node.use.x = from->node.use.x; + to->node.use.y = from->node.use.y; + to->node.use.w = from->node.use.w; + to->node.use.h = from->node.use.h; + to->node.use.isWidthSet = from->node.use.isWidthSet; + to->node.use.isHeightSet = from->node.use.isHeightSet; + to->node.use.symbol = from->node.use.symbol; + break; + } default: { break; } diff --git a/libfenrir/src/main/kotlin/androidx/media3/decoder/ffmpeg/FfmpegAudioRenderer.kt b/libfenrir/src/main/kotlin/androidx/media3/decoder/ffmpeg/FfmpegAudioRenderer.kt index 6cba9f4e9..d902c4ae2 100644 --- a/libfenrir/src/main/kotlin/androidx/media3/decoder/ffmpeg/FfmpegAudioRenderer.kt +++ b/libfenrir/src/main/kotlin/androidx/media3/decoder/ffmpeg/FfmpegAudioRenderer.kt @@ -29,7 +29,6 @@ import androidx.media3.exoplayer.RendererCapabilities import androidx.media3.exoplayer.audio.AudioRendererEventListener import androidx.media3.exoplayer.audio.AudioSink import androidx.media3.exoplayer.audio.DecoderAudioRenderer -import androidx.media3.exoplayer.audio.DefaultAudioSink import dev.ragnarok.fenrir.module.FenrirNative /** @@ -37,22 +36,7 @@ import dev.ragnarok.fenrir.module.FenrirNative */ @UnstableApi @Suppress("UNUSED") -class FfmpegAudioRenderer -/** - * Creates a new instance. - * - * @param eventHandler A handler to use when delivering events to `eventListener`. May be - * null if delivery of events is not required. - * @param eventListener A listener of events. May be null if delivery of events is not required. - * @param audioSink The sink to which audio will be output. - */ - ( - eventHandler: Handler?, - eventListener: AudioRendererEventListener?, - audioSink: AudioSink -) : DecoderAudioRenderer(eventHandler, eventListener, audioSink) { - constructor() : this( /* eventHandler= */null, /* eventListener= */null) - +class FfmpegAudioRenderer : DecoderAudioRenderer { /** * Creates a new instance. * @@ -65,11 +49,21 @@ class FfmpegAudioRenderer eventHandler: Handler?, eventListener: AudioRendererEventListener?, vararg audioProcessors: AudioProcessor - ) : this( - eventHandler, - eventListener, - DefaultAudioSink.Builder().setAudioProcessors(audioProcessors).build() - ) + ) : super(eventHandler, eventListener, *audioProcessors) + + /** + * Creates a new instance. + * + * @param eventHandler A handler to use when delivering events to `eventListener`. May be + * null if delivery of events is not required. + * @param eventListener A listener of events. May be null if delivery of events is not required. + * @param audioSink The sink to which audio will be output. + */ + constructor( + eventHandler: Handler?, + eventListener: AudioRendererEventListener?, + audioSink: AudioSink + ) : super(eventHandler, eventListener, audioSink) override fun getName(): String { return TAG