Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CacheUtils: Cache a task with priority #5573

Closed
Romantic-LiXuefeng opened this issue Feb 27, 2019 · 12 comments
Closed

CacheUtils: Cache a task with priority #5573

Romantic-LiXuefeng opened this issue Feb 27, 2019 · 12 comments
Assignees
Labels

Comments

@Romantic-LiXuefeng
Copy link

Before filing a bug:

My user case: A playback task with priority PRIORITY_PLAYBACK, and at same time, a background
task with priority PRIORITY_DOWNLOAD.

  • When the playback task's state is buffering, the background task thread waiting.
  • When the playback task's state becomes ready, notify the background task thread continue loading.

As the state of the playback task changes between the buffering state and the ready state, the state of the background thread also changes in the waiting state and the running state.

The issue is: when the background task thread is in waiting state, the totalCachedBytes() return value changed.

Reproduction steps

Using the PreCacheProgressivePlayerActivity.java to replace PlayerActivity.java in demo.

package com.google.android.exoplayer2.demo;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.widget.FrameLayout;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSink;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.DummyDataSource;
import com.google.android.exoplayer2.upstream.FileDataSource;
import com.google.android.exoplayer2.upstream.FileDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.PriorityDataSource;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSink;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.PriorityTaskManager;
import com.google.android.exoplayer2.util.Util;

import java.io.IOException;

/*
 *  Pre-caching Progressive stream with priority demo
 */
public class PreCacheProgressivePlayerActivity extends Activity implements Player.EventListener {
    // TODO Use your available uris
    private static final String URI_TEST1 = "http://192.168.75.251:8081/Videos/tianjin.ts";
    private static final String URI_TEST2 = "http://192.168.75.251:8081/Videos/wdmy.ts";
    protected String userAgent;
    FrameLayout root;
    PlayerView playerView;
    private ExoPlayer player;
    private DefaultTrackSelector trackSelector;
    private ExoPlaybackException playbackException;
    private DataSource.Factory dataSourceFactory;
    private DefaultRenderersFactory renderersFactory;
    private DefaultLoadControl loadControl;
    private PriorityTaskManager mPriorityTaskManager;

    // Pre-caching
    private String fixedCacheKey;
    private DataSpec dataSpec;
    private CacheUtil.CachingCounters mCounters;
    private Cache downloadCache;

    private static final int UPDATE_CACHE_COUNTER = 1;
    @SuppressLint("HandlerLeak")
    private Handler updateCounterHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case UPDATE_CACHE_COUNTER:
                    double downloadPercentage = (mCounters.totalCachedBytes() * 100d)
                            / mCounters.contentLength;
                    Log.d("progressive_download", "Cache counter = [" + downloadPercentage + "], " +
                            "cached bytes = [" + mCounters.totalCachedBytes() + "], " +
                            "total content bytes = [" + mCounters.contentLength + "]");
                    if (downloadPercentage >= 100.0f){
                        // startPlayer(BEAR_URI);
                        Log.e("progressive_download","Cache successfully!");
                        updateCounterHandler.removeCallbacksAndMessages(null);
                    }else {
                        updateCounterHandler.sendEmptyMessageDelayed(UPDATE_CACHE_COUNTER,1000);
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.player_activity);
        playerView = findViewById(R.id.player_view);
        root = findViewById(R.id.root);
        playerView.requestFocus();
        int extensionRendererMode = DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF;
        renderersFactory =
                new DefaultRenderersFactory(this, extensionRendererMode);
        trackSelector = new DefaultTrackSelector();
        mCounters = new CacheUtil.CachingCounters();
        mPriorityTaskManager = new PriorityTaskManager();
       /*
        *  Start a task with high priority
        */
        startPlayer(URI_TEST1);
        /*
         * Pre-cache other task with low priority
         */
        Thread cacheThread = new Thread(new Cache1MTaskWithPriority(URI_TEST2));
        cacheThread.start();

        Log.d("progressive_download","Cache thread id = " +
                "[" + cacheThread.getName() + "]");

        updateCounterHandler.sendEmptyMessageDelayed(UPDATE_CACHE_COUNTER,1000);

    }


    private void startPlayer(String playUri) {
        /*
         * LoadControl with priority manager
         */
        loadControl = new DefaultLoadControl.Builder()
                .setPriorityTaskManager(mPriorityTaskManager)
                .createDefaultLoadControl();
        player = ExoPlayerFactory.newSimpleInstance(this,renderersFactory, trackSelector,loadControl);
        player.addListener(this);
        playerView.setPlayer(player);
        dataSourceFactory = buildDataSourceFactory();
        MediaSource mediaSource = buildMediaSource(Uri.parse(playUri),"");

        player.prepare(mediaSource);
        player.setPlayWhenReady(true);
    }

    /*
     * Test pre-cache with priority
     */
    class Cache1MTaskWithPriority implements Runnable{
        private String cacheUri;
        public Cache1MTaskWithPriority(String uri) {
            this.cacheUri = uri;
        }

        @Override
        public void run() {
            fixedCacheKey = CacheUtil.generateKey(Uri.parse(cacheUri));
            dataSpec = new DataSpec(Uri.parse(cacheUri),
                    0, 200 * 1024 * 1024, fixedCacheKey);

            /*
             * If a {@link PriorityTaskManager} is given, it's used to pause and resume caching depending
             * on {@code priority} and the priority of other tasks registered to the PriorityTaskManager.
             * Please note that it's the responsibility of the calling code to call{@link PriorityTaskManager#add}
             * to register with the manager before calling this method, and to call {@link PriorityTaskManager#remove}
             * afterwards to unregister.
             */
            mPriorityTaskManager.add(C.PRIORITY_DOWNLOAD);
            try {
                CacheUtil.cache(dataSpec,
                        getDownloadCache(),
                        buildPriorityCacheDataSource(false),
                        new byte[CacheUtil.DEFAULT_BUFFER_SIZE_BYTES],
                        mPriorityTaskManager,
                        C.PRIORITY_DOWNLOAD,
                        mCounters,
                        null,
                        false);
            } catch (IOException e) {
                Log.e("progressive_download","Pre-caching io exception!");
                e.printStackTrace();
            } catch (InterruptedException e) {
                Log.e("progressive_download","Pre-caching interrupt exception!");
                e.printStackTrace();
            }finally {
                mPriorityTaskManager.remove(C.PRIORITY_DOWNLOAD);
            }
            Log.e("progressive_download","Cache thread ended!");
        }
    }

    /**
     * Returns a new {@link CacheDataSource} instance. If {@code offline} is true, it can only read
     * data from the cache.
     */
    public CacheDataSource buildPriorityCacheDataSource(boolean offline) {
        DataSource cacheReadDataSource =  new FileDataSource();
        if (offline) {
            return new CacheDataSource(getDownloadCache(), DummyDataSource.INSTANCE,
                    cacheReadDataSource, null, CacheDataSource.FLAG_BLOCK_ON_CACHE, null);
        } else {
            DefaultDataSourceFactory upstreamFactory =
                    new DefaultDataSourceFactory(PreCacheProgressivePlayerActivity2.this, buildHttpDataSourceFactory());
            DataSink cacheWriteDataSink = new CacheDataSink(getDownloadCache(), CacheDataSource.DEFAULT_MAX_CACHE_FILE_SIZE);
            DataSource upstream = upstreamFactory.createDataSource();
            upstream = mPriorityTaskManager == null ? upstream
                    : new PriorityDataSource(upstream, mPriorityTaskManager, C.PRIORITY_DOWNLOAD);
            Log.e("progressive_download","Create priority upstream data source!");
            return new CacheDataSource(getDownloadCache(), upstream, cacheReadDataSource,
                    cacheWriteDataSink, CacheDataSource.FLAG_BLOCK_ON_CACHE, null);
        }
    }

    /** Returns a new DataSource factory. */
    private DataSource.Factory buildDataSourceFactory() {
        DefaultDataSourceFactory upstreamFactory =
                new DefaultDataSourceFactory(this, buildHttpDataSourceFactory());
        return buildReadOnlyCacheDataSource(upstreamFactory, getDownloadCache());
//        return buildCacheDataSource(upstreamFactory,getDownloadCache());
    }

    private CacheDataSourceFactory buildCacheDataSource(DefaultDataSourceFactory upstreamFactory,Cache cache){
        return new CacheDataSourceFactory(cache, upstreamFactory);
    }


    private CacheDataSourceFactory buildReadOnlyCacheDataSource(DefaultDataSourceFactory upstreamFactory, Cache cache) {
        return new CacheDataSourceFactory(
                cache,
                upstreamFactory,
                new FileDataSourceFactory(),
                /* cacheWriteDataSinkFactory= */ null,
                CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
                /* eventListener= */ null);
    }

    private synchronized Cache getDownloadCache() {
        downloadCache = ((DemoApplication)getApplication()).getDownloadCache();
        return downloadCache;
    }


    public HttpDataSource.Factory buildHttpDataSourceFactory() {
        userAgent = Util.getUserAgent(this, "ExoPlayerDemo");
        return new DefaultHttpDataSourceFactory(userAgent);
    }


    private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {
        @C.ContentType int type = Util.inferContentType(uri, overrideExtension);
        switch (type) {
            case C.TYPE_HLS:
                return new HlsMediaSource.Factory(dataSourceFactory)
                        .createMediaSource(uri);
            case C.TYPE_OTHER:
                return new ExtractorMediaSource.Factory(dataSourceFactory)
                        .createMediaSource(uri);
            default: {
                throw new IllegalStateException("Unsupported type: " + type);
            }
        }
    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        playbackException = error;
    }
    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        if (playbackState == Player.STATE_ENDED
                || (playbackState == Player.STATE_IDLE && playbackException != null)) {
            player.release();
        }
    }
    @Override
    public void onPause() {
        super.onPause();
        releasePlayer();
    }

    private void releasePlayer() {
        if (updateCounterHandler != null){
            updateCounterHandler.removeCallbacksAndMessages(null);
        }
        if (player != null) {
            player.release();
            player = null;
        }

    }

    // Activity input

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        // See whether the player view wants to handle media or DPAD keys events.
        return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
    }

}
02-27 16:20:09.322 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Internal playback thread id = [791]
02-27 16:20:09.342 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache thread id = [Thread-879]
02-27 16:20:09.352 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Create priority upstream data source!
02-27 16:20:09.352 742-792/com.google.android.exoplayer2.demo D/progressive_downloader: block length = [-209715200]
02-27 16:20:09.522 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Cache resolvedLength = [1160653344]
02-27 16:20:10.343 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.4757270812988281], cached bytes = [997672], total content bytes = [209715200]
02-27 16:20:11.024 742-791/com.google.android.exoplayer2.demo E/progressive_downloader: The playback source has highest priority!
02-27 16:20:11.034 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: The background cache source's priority is low, cause PriorityTooLowException
02-27 16:20:11.104 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Priority is low, block until the task is allowed to proceed! Thread id = [Thread-879] is waiting
02-27 16:20:11.354 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]
02-27 16:20:13.356 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]
02-27 16:20:14.357 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]
02-27 16:20:16.129 742-791/com.google.android.exoplayer2.demo D/progressive_downloader: Playback thread id= [ExoPlayerImplInternal:Handler], Notify....
02-27 16:20:16.129 742-791/com.google.android.exoplayer2.demo E/progressive_downloader: The playback source has buffered enough, need to download the background source!
02-27 16:20:16.129 742-792/com.google.android.exoplayer2.demo D/progressive_downloader: Thread id = [Thread-879] receive signal, continue running!
02-27 16:20:16.139 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Cache resolvedLength = [1160653344]
02-27 16:20:16.419 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [1.6212005615234375], cached bytes = [3399904], total content bytes = [209715200]
02-27 16:20:17.410 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [1.9615974426269531], cached bytes = [4116664], total content bytes = [209715200]
02-27 16:20:18.411 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [2.5919876098632813], cached bytes = [5435792], total content bytes = [209715200]
02-27 16:20:19.423 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [2.7873878479003906], cached bytes = [5845576], total content bytes = [209715200]
02-27 16:20:20.424 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [3.149188995361328], cached bytes = [6604328], total content bytes = [209715200]
02-27 16:20:21.425 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [3.7761268615722656], cached bytes = [7919112], total content bytes = [209715200]
02-27 16:20:22.426 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [4.6205596923828125], cached bytes = [9690016], total content bytes = [209715200]
02-27 16:20:23.427 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [5.547847747802734], cached bytes = [11634680], total content bytes = [209715200]
02-27 16:20:24.438 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [6.2969970703125], cached bytes = [13205760], total content bytes = [209715200]
02-27 16:20:25.439 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [7.209095001220703], cached bytes = [15118568], total content bytes = [209715200]
02-27 16:20:26.440 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [8.153644561767578], cached bytes = [17099432], total content bytes = [209715200]
02-27 16:20:27.431 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [8.971149444580078], cached bytes = [18813864], total content bytes = [209715200]
02-27 16:20:28.442 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [9.619491577148438], cached bytes = [20173536], total content bytes = [209715200]
02-27 16:20:29.443 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [9.919151306152344], cached bytes = [20801968], total content bytes = [209715200]
02-27 16:20:30.444 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [10.159431457519531], cached bytes = [21305872], total content bytes = [209715200]
02-27 16:20:31.445 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [11.032173156738281], cached bytes = [23136144], total content bytes = [209715200]
02-27 16:20:32.446 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [11.25381088256836], cached bytes = [23600952], total content bytes = [209715200]
02-27 16:20:33.457 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [11.938854217529297], cached bytes = [25037592], total content bytes = [209715200]
02-27 16:20:34.459 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [12.803203582763672], cached bytes = [26850264], total content bytes = [209715200]
02-27 16:20:35.460 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [13.68768310546875], cached bytes = [28706600], total content bytes = [209715200]
02-27 16:20:36.451 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [13.976295471191406], cached bytes = [29310416], total content bytes = [209715200]
02-27 16:20:37.452 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [14.423023223876953], cached bytes = [30247272], total content bytes = [209715200]
02-27 16:20:38.453 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [14.89944076538086], cached bytes = [31246392], total content bytes = [209715200]
02-27 16:20:39.454 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [15.134197235107422], cached bytes = [31738712], total content bytes = [209715200]
02-27 16:20:40.465 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [15.368263244628906], cached bytes = [32229584], total content bytes = [209715200]
02-27 16:20:41.466 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [16.336978912353516], cached bytes = [34261128], total content bytes = [209715200]
02-27 16:20:42.467 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [17.133769989013672], cached bytes = [35932120], total content bytes = [209715200]
02-27 16:20:43.478 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [18.11008071899414], cached bytes = [37979592], total content bytes = [209715200]
02-27 16:20:44.479 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [19.040130615234375], cached bytes = [39930048], total content bytes = [209715200]
02-27 16:20:45.480 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [19.876277923583984], cached bytes = [41685024], total content bytes = [209715200]
02-27 16:20:46.471 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [20.830493927001953], cached bytes = [43684712], total content bytes = [209715200]
02-27 16:20:47.472 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [21.790924072265625], cached bytes = [45698880], total content bytes = [209715200]
02-27 16:20:48.484 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [22.560787200927734], cached bytes = [47313400], total content bytes = [209715200]
02-27 16:20:49.485 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [23.01580047607422], cached bytes = [48267632], total content bytes = [209715200]
02-27 16:20:50.486 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [23.554359436035156], cached bytes = [49397072], total content bytes = [209715200]
02-27 16:20:51.487 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [24.287628173828125], cached bytes = [50934848], total content bytes = [209715200]
02-27 16:20:52.498 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [25.24322509765625], cached bytes = [52938880], total content bytes = [209715200]
02-27 16:20:53.499 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [25.955089569091797], cached bytes = [54431768], total content bytes = [209715200]
02-27 16:20:54.500 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [26.292724609375], cached bytes = [55139840], total content bytes = [209715200]
02-27 16:20:55.161 742-791/com.google.android.exoplayer2.demo E/progressive_downloader: The playback source has highest priority!
02-27 16:20:55.191 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: The background cache source's priority is low, cause PriorityTooLowException
02-27 16:20:55.221 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Priority is low, block until the task is allowed to proceed! Thread id = [Thread-879] is waiting
02-27 16:20:55.491 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [26.94106674194336], cached bytes = [56499512], total content bytes = [209715200]
02-27 16:20:57.493 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [26.94106674194336], cached bytes = [56499512], total content bytes = [209715200]
02-27 16:20:58.494 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [26.94106674194336], cached bytes = [56499512], total content bytes = [209715200]
02-27 16:20:59.015 742-791/com.google.android.exoplayer2.demo D/progressive_downloader: Playback thread id= [ExoPlayerImplInternal:Handler], Notify....
02-27 16:20:59.015 742-791/com.google.android.exoplayer2.demo E/progressive_downloader: The playback source has buffered enough, need to download the background source!
02-27 16:20:59.015 742-792/com.google.android.exoplayer2.demo D/progressive_downloader: Thread id = [Thread-879] receive signal, continue running!
02-27 16:20:59.025 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Cache resolvedLength = [1160653344]
02-27 16:20:59.505 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [50.62666702270508], cached bytes = [106171816], total content bytes = [209715200]
02-27 16:21:00.506 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [53.0777473449707], cached bytes = [111312104], total content bytes = [209715200]
02-27 16:21:01.507 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [53.37809753417969], cached bytes = [111941984], total content bytes = [209715200]
02-27 16:21:02.508 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [53.95463180541992], cached bytes = [113151064], total content bytes = [209715200]
02-27 16:21:03.510 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [54.61885452270508], cached bytes = [114544040], total content bytes = [209715200]
02-27 16:21:04.501 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [55.23957824707031], cached bytes = [115847240], total content bytes = [209715200]
02-27 16:21:05.512 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [55.967323303222656], cached bytes = [117371984], total content bytes = [209715200]
02-27 16:21:06.513 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [56.604618072509766], cached bytes = [118708488], total content bytes = [209715200]
02-27 16:21:07.514 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [57.4304084777832], cached bytes = [120440296], total content bytes = [209715200]
02-27 16:21:08.515 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [58.12294006347656], cached bytes = [121892640], total content bytes = [209715200]
02-27 16:21:09.516 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [58.383934020996094], cached bytes = [122439984], total content bytes = [209715200]
02-27 16:21:10.517 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [58.52478790283203], cached bytes = [122735376], total content bytes = [209715200]

At the beginning, when the background task thread's state is waiting, the totalCachedBytes() return value unchanged.

02-27 16:20:11.104 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Priority is low, block until the task is allowed to proceed! Thread id = [Thread-879] is waiting
02-27 16:20:11.354 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]
02-27 16:20:13.356 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]
02-27 16:20:14.357 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [0.8106002807617188], cached bytes = [1699952], total content bytes = [209715200]

But there are some abnormal situations. Look at these lines filtered by TAG["progressive_downloader"]. the totalCachedBytes() return from 56499512 to 106171816.

16:20:58.494 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [26.94106674194336], cached bytes = [56499512], total content bytes = [209715200]
02-27 16:20:59.015 742-791/com.google.android.exoplayer2.demo D/progressive_downloader: Playback thread id= [ExoPlayerImplInternal:Handler], Notify....
02-27 16:20:59.015 742-791/com.google.android.exoplayer2.demo E/progressive_downloader: The playback source has buffered enough, need to download the background source!
02-27 16:20:59.015 742-792/com.google.android.exoplayer2.demo D/progressive_downloader: Thread id = [Thread-879] receive signal, continue running!
02-27 16:20:59.025 742-792/com.google.android.exoplayer2.demo E/progressive_downloader: Cache resolvedLength = [1160653344]
02-27 16:20:59.505 742-742/com.google.android.exoplayer2.demo D/progressive_downloader: Cache counter = [50.62666702270508], cached bytes = [106171816], total content bytes = [209715200]
@AquilesCanta
Copy link
Contributor

AquilesCanta commented Feb 28, 2019

At what point are you making the cache thread wait?

In other words, from what you explain above, i'd expect something along the lines of

onPlayerStateChanged(..., int playbackState) {
  if (playbackState == STATE_BUFFERING) {
    cacheTask.pause();
  } else if (playbackState == STATE_READY) {
    cacheTask.continue();
}

But I don't see where that's happening. Can you clarify. It would also help if you removed any irrelevant piece of code in the sample.

@Romantic-LiXuefeng
Copy link
Author

Romantic-LiXuefeng commented Mar 1, 2019

  1. Used the PriorityDataSource with the background download task.
  2. Used the PriorityTaskManager to manager the playback task and download task.

In DefaultLoadControl, if the playback task needs to continue loading, register the task with high priority to the PriorityTaskManager, when the cache task with PriorityDataSource start to read, it found exits high priority task, the cache thread will wait. When the playback task buffered enough, it will unregister the high task, and notify the cache thread to download.

At what point are you making the cache thread wait?

The PriorityTaskManager controls the cache thread wait and resume.

@Romantic-LiXuefeng
Copy link
Author

I think that the sample don't have irrelevant piece of code.

@Romantic-LiXuefeng
Copy link
Author

CacheUtil.readAndDiscard()

      } catch (PriorityTaskManager.PriorityTooLowException exception) {
        // catch and try again
        Log.e("progressive_download","The background cache source's priority is " +
                "low, cause PriorityTooLowException");
      }

PriorityTaskManager.proceed()

public void proceed(int priority) throws InterruptedException {
    synchronized (lock) {
      while (highestPriority != priority) {
        Log.e("progressive_download","Priority is low, block until the task " +
                "is allowed to proceed! Thread id = [" + Thread.currentThread().getName() + "] is waiting");
        lock.wait();
        Log.d("progressive_download","Thread id = [" + Thread.currentThread().getName() + "] receive signal, continue running!");
      }
    }
  }

DefaultLoadControl.shouldContinueLoading()

if (priorityTaskManager != null && isBuffering != wasBuffering) {
      if (isBuffering) {
        priorityTaskManager.add(C.PRIORITY_PLAYBACK);
        Log.e("progressive_download","The playback source has highest priority!");
      } else {
        priorityTaskManager.remove(C.PRIORITY_PLAYBACK);
        Log.e("progressive_download“,"The playback source has buffered enough, " +
                "need to download the background source!");
      }
 }

I add logs at these points.

@Romantic-LiXuefeng
Copy link
Author

@AquilesCanta Did you already had the time to look into this issue? Is there anything I can do to support you?

@Romantic-LiXuefeng
Copy link
Author

Is there anyone looking at this issue? I think this is a bug. Is there anything I can do to support you?

@ojw28
Copy link
Contributor

ojw28 commented Mar 8, 2019

I'd suggest you make your version of the demo app available on GitHub somewhere, so we can easily reproduce what you're seeing without having to spend a lot of time replicating what you've done. Thanks!

@AquilesCanta
Copy link
Contributor

Sorry, lost track of this. @erdemguven could you take a look?

@Romantic-LiXuefeng, please provide a minimal fork as @ojw28 suggests. It will allow us to look into this faster.

@Romantic-LiXuefeng
Copy link
Author

Romantic-LiXuefeng commented Mar 12, 2019

@erdemguven @AquilesCanta @ojw28 As suggests, I make a demo project. Thanks for your help !
https://github.com/Romantic-LiXuefeng/ExoPlayer_Pre_Cache_Demo/tree/release-v2
You could filter logs with "progressive_download".

@marcochin
Copy link

marcochin commented Apr 16, 2019

Can confirm when the cache download pauses and the resumes because of priority switching, the CachingCounters.newlyCachedBytes (which is used to calculate CachingCounters.totalCachedBytes()) jumps up by quite a lot right when it resumes the download, always surpassing the download length specified in the DataSpec and even sometimes surpassing the original mp4 file size.

Hopefully, it's just the value that is wrong and everything else is working correctly.

Edit: Ran some tests and good news. It looks like just the value is wrong, but the file sizes of the downloaded items are correct.

@erdemguven
Copy link
Contributor

It looks like only a reporting problem. Already cached data is recounted when caching resumes. A fix will be committed soon.

tonihei pushed a commit that referenced this issue May 30, 2019
When caching is resumed, it starts from the initial position. This makes
more data to be reported as cached.

Issue:#5573
PiperOrigin-RevId: 250678841
@Romantic-LiXuefeng
Copy link
Author

Thanks! I'll close this issue.

ojw28 pushed a commit that referenced this issue Jun 3, 2019
When caching is resumed, it starts from the initial position. This makes
more data to be reported as cached.

Issue:#5573
PiperOrigin-RevId: 250678841
@google google locked and limited conversation to collaborators Oct 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

5 participants