optimize logs, users/related always refresh

This commit is contained in:
2020-05-21 08:43:34 +08:00
parent 21c93310ea
commit 5b8e02a04b
18 changed files with 164 additions and 116 deletions

View File

@ -28,15 +28,19 @@
<DebugType>portable</DebugType> <DebugType>portable</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath> <OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants> <DefineConstants>DEBUG;LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode> <AndroidLinkMode>None</AndroidLinkMode>
<ConsolePause>true</ConsolePause>
<EmbedAssembliesIntoApk></EmbedAssembliesIntoApk>
<AndroidSupportedAbis>arm64-v8a;armeabi-v7a;x86;x86_64</AndroidSupportedAbis>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType></DebugType> <DebugType></DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath> <OutputPath>bin\Release</OutputPath>
<DefineConstants>LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AndroidManagedSymbols>true</AndroidManagedSymbols> <AndroidManagedSymbols>true</AndroidManagedSymbols>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0.519" package="org.tsanie.pixiview" android:versionCode="8"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0.520" package="org.tsanie.pixiview" android:versionCode="9">
<uses-sdk android:minSdkVersion="25" android:targetSdkVersion="28" /> <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="28" />
<application android:label="Pixiview" android:icon="@mipmap/icon" android:roundIcon="@mipmap/icon_round"></application> <application android:label="Pixiview" android:icon="@mipmap/icon" android:roundIcon="@mipmap/icon_round"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

View File

@ -29,8 +29,8 @@
<string>com.apple.share-services</string> <string>com.apple.share-services</string>
</dict> </dict>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.519</string> <string>1.0.520</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>8</string> <string>9</string>
</dict> </dict>
</plist> </plist>

View File

@ -26,8 +26,8 @@ namespace Pixiview.iOS
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{ {
#if DEBUG #if LOG
App.DebugPrint($"url: {url}."); App.DebugPrint($"open url: {url}.");
#endif #endif
return App.OpenUrl(url); return App.OpenUrl(url);
} }

View File

@ -79,8 +79,8 @@
</dict> </dict>
</array> </array>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.519</string> <string>1.0.520</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>8</string> <string>9</string>
</dict> </dict>
</plist> </plist>

View File

@ -21,7 +21,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath> <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants> <DefineConstants>DEBUG;LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<MtouchArch>x86_64</MtouchArch> <MtouchArch>x86_64</MtouchArch>
@ -32,6 +32,7 @@
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath> <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<DefineConstants>LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<MtouchLink>None</MtouchLink> <MtouchLink>None</MtouchLink>
@ -42,7 +43,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath> <OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants> <DefineConstants>DEBUG;LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch> <MtouchArch>ARM64</MtouchArch>
@ -56,6 +57,7 @@
<DebugType>none</DebugType> <DebugType>none</DebugType>
<Optimize>true</Optimize> <Optimize>true</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath> <OutputPath>bin\iPhone\Release</OutputPath>
<DefineConstants>LOG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<MtouchArch>ARM64</MtouchArch> <MtouchArch>ARM64</MtouchArch>

View File

@ -1,5 +1,7 @@
using System; using System;
#if DEBUG
using System.Diagnostics; using System.Diagnostics;
#endif
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@ -44,7 +46,7 @@ namespace Pixiview
if (!string.IsNullOrEmpty(host) && port > 0) if (!string.IsNullOrEmpty(host) && port > 0)
{ {
Configs.Proxy = new System.Net.WebProxy(host, port); Configs.Proxy = new System.Net.WebProxy(host, port);
#if DEBUG #if LOG
DebugPrint($"load proxy: {host}:{port}"); DebugPrint($"load proxy: {host}:{port}");
#endif #endif
} }
@ -76,7 +78,7 @@ namespace Pixiview
{ {
return; return;
} }
#if DEBUG #if LOG
DebugPrint($"application theme: {theme}"); DebugPrint($"application theme: {theme}");
#endif #endif
ThemeBase themeInstance; ThemeBase themeInstance;
@ -117,17 +119,25 @@ namespace Pixiview
var theme = AppInfo.RequestedTheme; var theme = AppInfo.RequestedTheme;
SetTheme(theme); SetTheme(theme);
} }
#if DEBUG
public static void DebugPrint(string message) public static void DebugPrint(string message)
{ {
Debug.WriteLine("[{0:HH:mm:ss.ffff}] - {1}", DateTime.Now, message); Debug.WriteLine("[{0:HH:mm:ss.ffff}] - {1}", DateTime.Now, message);
} }
public static void DebugError(string category, string message) public static void DebugError(string category, string message)
{ {
Debug.Fail(string.Format("[{0:HH:mm:ss.ffff}] - {1} - {2}", DateTime.Now, category, message)); Debug.Fail(string.Format("[{0:HH:mm:ss.ffff}] - {1} - {2}", DateTime.Now, category, message));
} }
#else
public static void DebugPrint(string message)
{
Console.WriteLine("[Debug.Print] - {0}", message);
}
public static void DebugError(string category, string message)
{
Console.Error.WriteLine(string.Format("[Debug.Error] - {0} - {1}", category, message));
}
#endif
public static bool OpenUrl(Uri uri) public static bool OpenUrl(Uri uri)
{ {
var current = Current.MainPage; var current = Current.MainPage;

View File

@ -57,7 +57,7 @@ namespace Pixiview
BindingContext = this; BindingContext = this;
InitializeComponent(); InitializeComponent();
#if DEBUG #if LOG
App.DebugPrint($"folder: {Stores.PersonalFolder}"); App.DebugPrint($"folder: {Stores.PersonalFolder}");
App.DebugPrint($"cache: {Stores.CacheFolder}"); App.DebugPrint($"cache: {Stores.CacheFolder}");
#endif #endif

View File

@ -280,7 +280,7 @@ namespace Pixiview.Illust
if (bookmarkId != null) if (bookmarkId != null)
{ {
// not exists in remote any more // not exists in remote any more
#if DEBUG #if LOG
App.DebugPrint($"remove bookmark ({bookmarkId}) - {b.Id}: {b.Title}"); App.DebugPrint($"remove bookmark ({bookmarkId}) - {b.Id}: {b.Title}");
#endif #endif
nows.RemoveAt(i); nows.RemoveAt(i);
@ -289,7 +289,7 @@ namespace Pixiview.Illust
else if (bookmarkId != bookmark.BookmarkId) else if (bookmarkId != bookmark.BookmarkId)
{ {
// update bookmark id // update bookmark id
#if DEBUG #if LOG
App.DebugPrint($"change bookmark ({bookmarkId}) to ({bookmark.BookmarkId}) - {b.Id}: {b.Title}"); App.DebugPrint($"change bookmark ({bookmarkId}) to ({bookmark.BookmarkId}) - {b.Id}: {b.Title}");
#endif #endif
b.BookmarkId = bookmark.BookmarkId; b.BookmarkId = bookmark.BookmarkId;
@ -303,7 +303,7 @@ namespace Pixiview.Illust
for (var i = 0; i < list.Length; i++) for (var i = 0; i < list.Length; i++)
{ {
var item = list[i]; var item = list[i];
#if DEBUG #if LOG
App.DebugPrint($"add bookmark ({item.BookmarkId}) - {item.Id}: {item.Title}"); App.DebugPrint($"add bookmark ({item.BookmarkId}) - {item.Id}: {item.Title}");
#endif #endif
item.Image = StyleDefinition.DownloadBackground; item.Image = StyleDefinition.DownloadBackground;
@ -316,7 +316,7 @@ namespace Pixiview.Illust
return; return;
} }
ParallelTask.Start(0, list.Length, Configs.MaxPageThreads, i => ParallelTask.Start("favorite.loadimages", 0, list.Length, Configs.MaxPageThreads, i =>
{ {
var illustItem = list[i]; var illustItem = list[i];
var data = Stores.LoadIllustPreloadData(illustItem.Id); var data = Stores.LoadIllustPreloadData(illustItem.Id);

View File

@ -595,7 +595,7 @@ namespace Pixiview.Illust
task.Dispose(); task.Dispose();
task = null; task = null;
} }
task = ParallelTask.Start(0, collection.Count, Configs.MaxThreads, i => task = ParallelTask.Start("collection.load", 0, collection.Count, Configs.MaxThreads, i =>
{ {
if (!collection.Running) if (!collection.Running)
{ {

View File

@ -45,7 +45,7 @@ namespace Pixiview.Illust
if (startIndex < 0) if (startIndex < 0)
{ {
// init // init
data = Stores.LoadIllustRecommendsInitData(illustItem.Id, force); data = Stores.LoadIllustRecommendsInitData(illustItem.Id);
if (data == null || data.body == null) if (data == null || data.body == null)
{ {
return null; return null;

View File

@ -400,7 +400,7 @@ namespace Pixiview.Illust
task.Dispose(); task.Dispose();
task = null; task = null;
} }
task = ParallelTask.Start(0, items.Length, Configs.MaxPageThreads, i => task = ParallelTask.Start("view.illusts", 0, items.Length, Configs.MaxPageThreads, i =>
{ {
DoLoadImage(i); DoLoadImage(i);
return true; return true;
@ -545,6 +545,10 @@ namespace Pixiview.Illust
{ {
return; return;
} }
if (Configs.Cookie == null)
{
return;
}
if (!add && string.IsNullOrEmpty(bookmarkId)) if (!add && string.IsNullOrEmpty(bookmarkId))
{ {
return; return;

View File

@ -102,7 +102,7 @@ namespace Pixiview
{ {
Preferences.Set(Configs.IsOnR18Key, r18); Preferences.Set(Configs.IsOnR18Key, r18);
Configs.IsOnR18 = r18; Configs.IsOnR18 = r18;
#if DEBUG #if LOG
App.DebugPrint($"r-18 filter: {r18}"); App.DebugPrint($"r-18 filter: {r18}");
#endif #endif
} }
@ -111,7 +111,7 @@ namespace Pixiview
{ {
Preferences.Set(Configs.SyncFavTypeKey, syncType); Preferences.Set(Configs.SyncFavTypeKey, syncType);
Configs.SyncFavType = (SyncType)syncType; Configs.SyncFavType = (SyncType)syncType;
#if DEBUG #if LOG
App.DebugPrint($"favorite sync type changed to {Configs.SyncFavType}"); App.DebugPrint($"favorite sync type changed to {Configs.SyncFavType}");
#endif #endif
} }
@ -134,7 +134,7 @@ namespace Pixiview
if (!string.IsNullOrEmpty(h) && pt > 0) if (!string.IsNullOrEmpty(h) && pt > 0)
{ {
Configs.Proxy = new System.Net.WebProxy(h, pt); Configs.Proxy = new System.Net.WebProxy(h, pt);
#if DEBUG #if LOG
App.DebugPrint($"set proxy to: {h}:{pt}"); App.DebugPrint($"set proxy to: {h}:{pt}");
#endif #endif
} }
@ -151,7 +151,7 @@ namespace Pixiview
if (proxy != null) if (proxy != null)
{ {
Configs.Proxy = null; Configs.Proxy = null;
#if DEBUG #if LOG
App.DebugPrint("clear proxy"); App.DebugPrint("clear proxy");
#endif #endif
} }
@ -170,7 +170,7 @@ namespace Pixiview
{ {
session = session.Substring(0, index); session = session.Substring(0, index);
Configs.SetUserId(session, true); Configs.SetUserId(session, true);
#if DEBUG #if LOG
App.DebugPrint($"cookie changed, user id: {session}"); App.DebugPrint($"cookie changed, user id: {session}");
#endif #endif
} }

View File

@ -132,7 +132,7 @@ namespace Pixiview.UI
{ {
if (Tap.IsBusy) if (Tap.IsBusy)
{ {
#if DEBUG #if LOG
App.DebugPrint("gesture recognizer is now busy..."); App.DebugPrint("gesture recognizer is now busy...");
#endif #endif
return; return;

View File

@ -109,7 +109,7 @@ namespace Pixiview.Utils
{ {
Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentUICulture = ci;
#if DEBUG #if LOG
App.DebugPrint($"CurrentCulture set: {ci.Name}"); App.DebugPrint($"CurrentCulture set: {ci.Name}");
#endif #endif
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
@ -96,19 +97,19 @@ namespace Pixiview.Utils
public class ParallelTask : IDisposable public class ParallelTask : IDisposable
{ {
public static ParallelTask Start(int from, int toExclusive, int maxCount, Predicate<int> action, Action complete = null) public static ParallelTask Start(string tag, int from, int toExclusive, int maxCount, Predicate<int> action, Action complete = null)
{ {
if (toExclusive <= from) if (toExclusive <= from)
{ {
if (complete != null) if (complete != null)
{ {
ThreadPool.QueueUserWorkItem(o => complete()); Task.Run(complete);
} }
return null; return null;
} }
var task = new ParallelTask(from, toExclusive, maxCount, action, complete); var task = new ParallelTask(tag, from, toExclusive, maxCount, action, complete);
//Task.Run(task.Start); Task.Run(task.Start);
ThreadPool.QueueUserWorkItem(task.Start); //ThreadPool.QueueUserWorkItem(task.Start);
return task; return task;
} }
@ -116,13 +117,14 @@ namespace Pixiview.Utils
private int count; private int count;
private bool disposed; private bool disposed;
private readonly string tag;
private readonly int max; private readonly int max;
private readonly int from; private readonly int from;
private readonly int to; private readonly int to;
private readonly Predicate<int> action; private readonly Predicate<int> action;
private readonly Action complete; private readonly Action complete;
private ParallelTask(int from, int to, int maxCount, Predicate<int> action, Action complete) private ParallelTask(string tag, int from, int to, int maxCount, Predicate<int> action, Action complete)
{ {
if (maxCount <= 0) if (maxCount <= 0)
{ {
@ -133,14 +135,16 @@ namespace Pixiview.Utils
{ {
throw new ArgumentOutOfRangeException(nameof(from)); throw new ArgumentOutOfRangeException(nameof(from));
} }
this.tag = tag;
this.from = from; this.from = from;
this.to = to; this.to = to;
this.action = action; this.action = action;
this.complete = complete; this.complete = complete;
} }
private void Start(object o) private void Start()
{ {
var list = new List<Task>();
for (int i = from; i < to; i++) for (int i = from; i < to; i++)
{ {
var index = i; var index = i;
@ -152,8 +156,8 @@ namespace Pixiview.Utils
} }
if (disposed) if (disposed)
{ {
#if DEBUG #if LOG
App.DebugPrint($"parallel task determinate, disposed"); App.DebugPrint($"parallel task determinate, disposed ({tag})");
#endif #endif
return; return;
} }
@ -163,7 +167,7 @@ namespace Pixiview.Utils
{ {
count++; count++;
} }
Task.Run(() => list.Add(Task.Run(() =>
{ {
try try
{ {
@ -174,7 +178,7 @@ namespace Pixiview.Utils
} }
catch (Exception ex) catch (Exception ex)
{ {
App.DebugError("parallel.start", $"failed to run action, index: {i}, error: {ex.Message}"); App.DebugError("parallel.start ({tag})", $"failed to run action, index: {i}, error: {ex.Message}");
} }
finally finally
{ {
@ -183,10 +187,21 @@ namespace Pixiview.Utils
count--; count--;
} }
} }
}); }));
} }
#if DEBUG while (count > 0)
App.DebugPrint($"parallel task done"); {
if (disposed)
{
#if LOG
App.DebugPrint($"parallel task determinate, disposed ({tag})");
#endif
return;
}
Thread.Sleep(100);
}
#if LOG
App.DebugPrint($"parallel task done ({tag})");
#endif #endif
complete?.Invoke(); complete?.Invoke();
} }

View File

@ -29,7 +29,7 @@ namespace Pixiview.Utils
private const string preloadsFolder = "preloads"; private const string preloadsFolder = "preloads";
private const string thumbFolder = "img-thumb"; private const string thumbFolder = "img-thumb";
private const string userFolder = "user-profile"; private const string userFolder = "user-profile";
private const string recommendsFolder = "recommends"; //private const string recommendsFolder = "recommends";
public static bool NetworkAvailable public static bool NetworkAvailable
{ {
@ -238,18 +238,17 @@ namespace Pixiview.Utils
return result; return result;
} }
public static IllustRecommendsData LoadIllustRecommendsInitData(string id, bool force = false) public static IllustRecommendsData LoadIllustRecommendsInitData(string id)
{ {
var file = Path.Combine(CacheFolder, recommendsFolder, $"{id}.json"); //var file = Path.Combine(CacheFolder, recommendsFolder, $"{id}.json");
var result = HttpUtility.LoadObject<IllustRecommendsData>( var result = HttpUtility.LoadObject<IllustRecommendsData>(
file, null,
string.Format(Configs.UrlIllustRecommendsInit, id), string.Format(Configs.UrlIllustRecommendsInit, id),
string.Format(Configs.RefererIllust, id), string.Format(Configs.RefererIllust, id),
out _, out _);
force: force);
if (result == null || result.error) if (result == null || result.error)
{ {
App.DebugPrint($"error when load recommends init data: {result?.message}, force({force})"); App.DebugPrint($"error when load recommends init data: {result?.message}");
} }
return result; return result;
} }
@ -303,7 +302,7 @@ namespace Pixiview.Utils
} }
else else
{ {
#if DEBUG #if LOG
App.DebugPrint($"current csrf token: {result.token}"); App.DebugPrint($"current csrf token: {result.token}");
#endif #endif
Configs.CsrfToken = result.token; Configs.CsrfToken = result.token;
@ -338,7 +337,7 @@ namespace Pixiview.Utils
} }
else else
{ {
#if DEBUG #if LOG
App.DebugPrint($"successs, bookmark id: {result.body.last_bookmark_id}, status: {result.body.stacc_status_id}"); App.DebugPrint($"successs, bookmark id: {result.body.last_bookmark_id}, status: {result.body.stacc_status_id}");
#endif #endif
return result.body.last_bookmark_id; return result.body.last_bookmark_id;
@ -374,7 +373,7 @@ namespace Pixiview.Utils
App.DebugPrint("failed to delete bookmark, result is null"); App.DebugPrint("failed to delete bookmark, result is null");
return false; return false;
} }
#if DEBUG #if LOG
App.DebugPrint($"successs, delete bookmark"); App.DebugPrint($"successs, delete bookmark");
#endif #endif
return true; return true;

View File

@ -30,6 +30,7 @@ namespace Pixiview.Utils
private readonly ImageSource[] frames; private readonly ImageSource[] frames;
private Timer timer; private Timer timer;
private int index = 0; private int index = 0;
private ParallelTask downloadTask;
public bool IsPlaying { get; private set; } public bool IsPlaying { get; private set; }
public readonly int FrameCount; public readonly int FrameCount;
@ -51,6 +52,11 @@ namespace Pixiview.Utils
{ {
TogglePlay(false); TogglePlay(false);
} }
if (downloadTask != null)
{
downloadTask.Dispose();
downloadTask = null;
}
ClearTimer(); ClearTimer();
} }
@ -178,7 +184,7 @@ namespace Pixiview.Utils
var url = ugoira.originalSrc; var url = ugoira.originalSrc;
var id = detailItem.Id; var id = detailItem.Id;
var (size, lastModified, client) = HttpUtility.GetUgoiraHeader(url, id); var (size, lastModified, client) = HttpUtility.GetUgoiraHeader(url, id);
#if DEBUG #if LOG
App.DebugPrint($"starting download ugoira: {size} bytes, last modified: {lastModified}"); App.DebugPrint($"starting download ugoira: {size} bytes, last modified: {lastModified}");
#endif #endif
@ -283,7 +289,12 @@ namespace Pixiview.Utils
} }
} }
ParallelTask.Start(0, inSegs.Count, 2, i => if (downloadTask != null)
{
downloadTask.Dispose();
downloadTask = null;
}
downloadTask = ParallelTask.Start("ugoira.download", 0, inSegs.Count, 2, i =>
{ {
var seg = inSegs[i]; var seg = inSegs[i];
#if DEBUG #if DEBUG
@ -325,8 +336,8 @@ namespace Pixiview.Utils
} }
} }
} }
#if DEBUG #if LOG
App.DebugPrint("download over"); App.DebugPrint("load frames over");
#endif #endif
} }
} }
@ -454,78 +465,81 @@ namespace Pixiview.Utils
#endif #endif
for (int i = 0; i < images.Length; i++) for (int i = 0; i < images.Length; i++)
{ {
while (true) while (!writerInput.ReadyForMoreMediaData)
{ {
if (writerInput.ReadyForMoreMediaData) lock (sync)
{ {
// get pixel buffer and fill it with the image if (timer == null)
using (CVPixelBuffer pixelBufferImage = pixelBufferAdaptor.PixelBufferPool.CreatePixelBuffer())
{ {
pixelBufferImage.Lock(CVPixelBufferLock.None); return null;
}
}
Thread.Sleep(50);
}
// get pixel buffer and fill it with the image
using (CVPixelBuffer pixelBufferImage = pixelBufferAdaptor.PixelBufferPool.CreatePixelBuffer())
{
pixelBufferImage.Lock(CVPixelBufferLock.None);
try try
{
IntPtr pxdata = pixelBufferImage.BaseAddress;
if (pxdata != IntPtr.Zero)
{
using (var rgbColorSpace = CGColorSpace.CreateDeviceRGB())
{ {
IntPtr pxdata = pixelBufferImage.BaseAddress; var cgImage = images[i].CGImage;
var width = cgImage.Width;
if (pxdata != IntPtr.Zero) var height = cgImage.Height;
var bitsPerComponent = cgImage.BitsPerComponent;
var bytesPerRow = cgImage.BytesPerRow;
// padding to 64
var bytes = bytesPerRow >> 6 << 6;
if (bytes < bytesPerRow)
{ {
using (var rgbColorSpace = CGColorSpace.CreateDeviceRGB()) bytes += 64;
{ }
var cgImage = images[i].CGImage;
var width = cgImage.Width;
var height = cgImage.Height;
var bitsPerComponent = cgImage.BitsPerComponent;
var bytesPerRow = cgImage.BytesPerRow;
// padding to 64
var bytes = bytesPerRow >> 6 << 6;
if (bytes < bytesPerRow)
{
bytes += 64;
}
#if DEBUG #if DEBUG
if (!log) if (!log)
{ {
log = true; log = true;
App.DebugPrint($"animation, width: {width}, height: {height}, type: {cgImage.UTType}\n" + App.DebugPrint($"animation, width: {width}, height: {height}, type: {cgImage.UTType}\n" +
$"bitmapInfo: {cgImage.BitmapInfo}\n" + $"bitmapInfo: {cgImage.BitmapInfo}\n" +
$"bpc: {bitsPerComponent}\n" + $"bpc: {bitsPerComponent}\n" +
$"bpp: {cgImage.BitsPerPixel}\n" + $"bpp: {cgImage.BitsPerPixel}\n" +
$"calculated: {bytesPerRow} => {bytes}"); $"calculated: {bytesPerRow} => {bytes}");
} }
#endif #endif
using (CGBitmapContext bitmapContext = new CGBitmapContext( using (CGBitmapContext bitmapContext = new CGBitmapContext(
pxdata, width, height, pxdata, width, height,
bitsPerComponent, bitsPerComponent,
bytes, bytes,
rgbColorSpace, rgbColorSpace,
CGImageAlphaInfo.NoneSkipFirst)) CGImageAlphaInfo.NoneSkipFirst))
{ {
if (bitmapContext != null) if (bitmapContext != null)
{ {
bitmapContext.DrawImage(new CGRect(0, 0, width, height), cgImage); bitmapContext.DrawImage(new CGRect(0, 0, width, height), cgImage);
}
}
} }
} }
} }
finally
{
pixelBufferImage.Unlock(CVPixelBufferLock.None);
}
// and finally append buffer to adapter
if (pixelBufferAdaptor.AssetWriterInput.ReadyForMoreMediaData && pixelBufferImage != null)
{
pixelBufferAdaptor.AppendPixelBufferWithPresentationTime(pixelBufferImage, lastTime);
}
} }
var frameTime = new CMTime(ugoira.frames[i].delay, 1000);
lastTime = CMTime.Add(lastTime, frameTime);
break;
} }
Thread.Sleep(32); finally
{
pixelBufferImage.Unlock(CVPixelBufferLock.None);
}
// and finally append buffer to adapter
if (pixelBufferAdaptor.AssetWriterInput.ReadyForMoreMediaData && pixelBufferImage != null)
{
pixelBufferAdaptor.AppendPixelBufferWithPresentationTime(pixelBufferImage, lastTime);
}
} }
var frameTime = new CMTime(ugoira.frames[i].delay, 1000);
lastTime = CMTime.Add(lastTime, frameTime);
} }
writerInput.MarkAsFinished(); writerInput.MarkAsFinished();
await videoWriter.FinishWritingAsync(); await videoWriter.FinishWritingAsync();