JCodecでh.264ファイルからAndroidのBitmapを取得(任意のフレーム)

JCodecを使って任意のフレームを取得してみます。勘ですぐに気づくと思いますが、nextFrame()をひたすら読みだせばできそうです。 nextFrame() が返すオブジェクトのメンバーに frameNoというメンバもあります。

    //ダメな例
    fun getFrame(pos : Long) : Bitmap{
        val file = File("/sdcard/000.h264")
        val buf = NIOUtils.fetchFromFile(file)
        val es = BufferH264ES(buf)
        var nextFrame  =  es.nextFrame()
        val decoder = H264Decoder()
        val pic = Picture.create(1280, 1024, ColorSpace.YUV420)
        while(nextFrame != null && nextFrame.frameNo != pos){
            nextFrame  =  es.nextFrame()
        }
        val op = decoder.decodeFrame(nextFrame.data, pic.data).cropped()
        return AndroidUtil.toBitmap(op)
    }

これで指定したフレームのビットマップが得られそうに思うじゃないですか。ダメです。h.264は前フレームとの (正確な言い方じゃないけど) 差分を使います。なので、フレームごとにデコードしなければだめです。

    fun getFrame(pos : Long) : Bitmap{
        val file = File("/sdcard/000.h264")
        val buf = NIOUtils.fetchFromFile(file)
        val es = BufferH264ES(buf)
        var nextFrame  =  es.nextFrame()
        val decoder = H264Decoder()
        val pic = Picture.create(1280, 1024, ColorSpace.YUV420)
        while(nextFrame != null && nextFrame.frameNo != pos){
            val op = decoder.decodeFrame(nextFrame.data, pic.data)
            nextFrame  =  es.nextFrame()
        }
        val op = decoder.decodeFrame(nextFrame.data, pic.data).cropped()
        return AndroidUtil.toBitmap(op)
    }

これで取得できるのですが、終わりのほうのフレームが欲しい時に、これでは効率が悪いですよね?ということで、次に続く。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です