Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Apr 25 2018 07:30
    hirohitokato closed #6
  • Oct 20 2017 05:16

    hirohitokato on master

    Update README.md (compare)

  • Oct 20 2017 05:15

    hirohitokato on master

    Update README.md (compare)

  • Oct 20 2017 02:51
    hirohitokato closed #8
  • Oct 20 2017 02:51
    hirohitokato commented #8
  • Oct 20 2017 02:50
    hirohitokato closed #7
  • Oct 20 2017 02:50
    hirohitokato commented #7
  • Oct 19 2017 11:15

    hirohitokato on 0.6.0

    (compare)

  • Oct 19 2017 11:14

    hirohitokato on v0.6.1

    (compare)

  • Oct 19 2017 11:14

    hirohitokato on 0.8.0

    (compare)

  • Oct 19 2017 11:13

    hirohitokato on master

    Bump the version, update README… (compare)

  • Oct 19 2017 11:07

    hirohitokato on swift4

    (compare)

  • Oct 19 2017 11:07

    hirohitokato on master

    Update build setting to swift4 protocol `Printable,DebugPrinta… `CMSampleBufferRef` to `CMSampl… and 29 more (compare)

  • Oct 19 2017 11:07
    hirohitokato closed #9
  • Oct 19 2017 11:07
    hirohitokato assigned #9
  • Oct 19 2017 11:07
    hirohitokato opened #9
  • Oct 19 2017 11:06

    hirohitokato on swift4

    Resolve fatal error(1): Add pri… Reconnect IBActions Update copyright year and 1 more (compare)

  • Oct 19 2017 10:35

    hirohitokato on swift4

    Update build setting to swift4 protocol `Printable,DebugPrinta… `CMSampleBufferRef` to `CMSampl… and 24 more (compare)

  • Jun 08 2017 07:51
    iosfitness opened #8
  • Nov 30 2015 18:44
    jainanshul commented #7
Norio Nomura
@norio-nomura
Gitterのバッジだけ浮いてる
Hirohito Kato
@hirohitokato
ですね…。
Norio Nomura
@norio-nomura
gitterHQ/gitterへ意見を書きに行ったら、まさに同じことを言ってる人が居たよ。
Hirohito Kato
@hirohitokato
www
Hirohito Kato
@hirohitokato
1秒くらいのムービーを連続再生しているときにスライダーを動かすと、頻繁にcopyNextSampleBuffer()でハングすることに気付きました。
Hirohito Kato
@hirohitokato
らちがあかないので、遅ればせながらバグレポしました。 19860056
Norio Nomura
@norio-nomura
その条件は追試してあげられそうにないかな
Hirohito Kato
@hirohitokato

ありがとうございます。眠い中で書いたので、何か変な表現になってました。問題を改めて整理すると、

  • 1秒前後のムービーを複数用意
  • Playbackモードで再生開始
  • 画面下部のスライダーを頻繁に操作して、再生位置を変更

という条件・操作を行うと、再生位置変更によるAssetReader.startReading()からの最初のcopyNextSampleBuffer()で頻繁にハングします。ちなみに短いムービーの方が再現確率が高いのですが、理由はまだ分かっていません。

AVAssetReader.cancelReading()の説明に「バックグラウンドでの先読みをキャンセルする」とあるので、その処理とstartReading()がかち合って問題になっているのかなあと思いました。が、上記2つのAPIが近い時間で実行されないようにしても、変わらず。謎です。
Norio Nomura
@norio-nomura
これと同じく、track:0がオーディオ、track:1がビデオで起きるなら、以前AVMutableComposition作成時にassetをそのまま入れる、をやった時に気にしていたような記憶が。track:0がオーディオになるって、結局そのまなんだっけ?
Hirohito Kato
@hirohitokato
トラック逆転はそのままですね。あ、言い忘れてました。再現させたデータはビデオトラックのみのデータです。調べてますが、分からないですね、これ…。
Norio Nomura
@norio-nomura
とりあえずビルド通らん。
Hirohito Kato
@hirohitokato
もしかしたらas!をgithubにpushしてなかったかも…
Norio Nomura
@norio-nomura
うい。2箇所as!にしてiPhone 5s w/iOS 8.1.3で動かしてみた。
Hirohito Kato
@hirohitokato
手っ取り早く問題を確認できる、サンプルムービー同梱版を Dropboxにzipファイルとして保存しました。github上のプロジェクトに、単にログを埋め込みムービーをバンドルしただけです。
再生だけなら大丈夫そうですが、スライダーを使って再生位置を変えようとすると、高確率でハング(=メインスレッドで取りに行くcopyNextSampleBuffer()でストール)するはずです。…あ、でも8.1.3だと普通に再生しているだけでもハングすることがあるかもです。某βだと再生だけなら安定してますが。
Norio Nomura
@norio-nomura
ダウンロードしました。
Norio Nomura
@norio-nomura
デッドロックしてるような。
Hirohito Kato
@hirohitokato
ですです。困ったものです…
(ハングだと意味が違うことに気付きました…)
Norio Nomura
@norio-nomura
これはdispatch_syncdispatch_asyncのデッドロックだよ。
syncのなかでasyncを呼んでるここ
    func nextSampleBuffer() -> (sbuf:CMSampleBufferRef, frameDuration:CMTime)! {
        var result: (sbuf:CMSampleBufferRef, frameDuration:CMTime)! = nil
        sync { me in
            if me._currentSampleBuffer != nil {
                result = me._currentSampleBuffer
                me._currentSampleBuffer = nil
            } else {
                result = me._prepareNextBuffer()
            }

            me.async { me in
                me._currentSampleBuffer = me._prepareNextBuffer()
            }
        }
        return result
    }
Hirohito Kato
@hirohitokato
ちょっと待ってください?!
Norio Nomura
@norio-nomura
画面が固まったところで、Debug>Pause
⌘6でDebug Navigatorを表示
Hirohito Kato
@hirohitokato
その確認はさんざんしていたのですが、いやしかし、この処理は毎回通るはずなので、ランダムにデッドロックするというのがまだ理解できてないです。
ちょっと確認してきます。
Norio Nomura
@norio-nomura
先日「シリアルキューは呼び出し元スレッドで実行される」って話をしましたよね。
あれには条件があって、キューが空の時は呼び出し元スレッドで実行されます。
Hirohito Kato
@hirohitokato
空のとき、ですか。
Norio Nomura
@norio-nomura
あと、既にキューに処理待ちのブロックが入ってて、別スレッドで実行されているときには、そのスレッドで実行されるようにキューに積まれます。
あいや、違うな。
ごめん、違うわ。
Hirohito Kato
@hirohitokato
上(アプリ)でシリアライズしてても、AVFoundationからしてみれば複数スレッドから呼ばれるからまずい、という可能性はあるような気がしてきました。
えっ
いやしかし、ありがとうございます。
Norio Nomura
@norio-nomura
copyNextSampleBuffer()がスレッドセーフじゃないのかな。
Hirohito Kato
@hirohitokato
その可能性は高いです…。
Norio Nomura
@norio-nomura
結局、今のコードだとスレッドを固定できてないもんね。
Hirohito Kato
@hirohitokato
そうなんですよね。そこに一縷の望みをかけるべきか…。明日にでも試してみます!
Hirohito Kato
@hirohitokato
ためしに全部メインスレッドで実行してみるか…
Hirohito Kato
@hirohitokato
ためしにsync/asyncメソッドを、dispatch_〜を呼ばずに実行してみたら(多分これで全部メインスレッドになるはず)、見事にデッドロック(?)が起こりました。もうちょっと見てみます。
Hirohito Kato
@hirohitokato
うん、⌘-6のDebug Navigatorで見ても、アプリだけ見ればメインスレッドで自縄自縛していました。しかしシステムライブラリではたくさんスレッドを起動しているという、手を出せない状況だこれ。
Norio Nomura
@norio-nomura
頻繁に作り直すAVFoundationのオブジェクトがあるなら、それの解放タイミングを見直してみるとか?いま出先なのでコード読めないけど、例えばキャンセルした後とか。
Hirohito Kato
@hirohitokato
解放タイミング(=cancelReading/stopLoading)を遅らせることは試していませんでした。やってみます!
Norio Nomura
@norio-nomura
何かの処理が終わらないうちにオブジェクトがいなくなってるような気がするんだよね。
Hirohito Kato
@hirohitokato

解放タイミングを、キャンセルしてから0.1sごとにしてみるべく以下のコードを書いて動かしてみましたが、残念なことに同じようにロックしてしまいました。メインスレッドだけで実行しても、同様。

    private var _dustBox = [AssetReaderFragment]()
    func f() {
        if !self._dustBox.isEmpty {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))), self._decodeQueue) {
                self._dustBox.removeAtIndex(0)
                self.f()
            }
        }
    }
    func cancelReading(async asyncFlag: Bool=true) {
        let operation = { [unowned self] ()->Void in
            // 要素をゴミ箱に移動
            self._dustBox = self._readers
            self._readers.removeAll(keepCapacity: false)

            // ゴミ箱の要素を少しずつ削除
            self.f()
        }
        if asyncFlag {
            async { me in operation() }
        } else {
            operation()
        }
    }

とほほ

Norio Nomura
@norio-nomura
Gitterのウィンドウを大きくすると、右側にActivityってのが出てくるの知らなかった。
Hirohito Kato
@hirohitokato
本当ですね。意識してませんでした。