/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.chunk.mpegts;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import com.ttProject.media.mpegts.field.AdaptationField;
import com.ttProject.media.mpegts.packet.Pes;
/**
* videoDataは簡単に移動ができないので(keyFrameの位置をずらしたりする場合は再変換しなければいけないため)
* pesベースで取り込んで持っておいてOK
*/
public class VideoDataList extends MediaDataList {
/** ロガー */
@SuppressWarnings("unused")
private final Logger logger = Logger.getLogger(VideoDataList.class);
/** 映像のpesデータリスト */
private final List<Pes> videoPesList = new ArrayList<Pes>();
/** 映像のキーフレームの先頭の部分のpesリスト */
private final List<Pes> keyPesList = new ArrayList<Pes>();
/** 最終pesデータのpts値記録 */
private long lastDataPts = -1L;
/**
* 保持データサイズを応答します。
* @return
*/
public int getListCount() {
return videoPesList.size();
}
/**
* pesデータを追記する
* @param pes
*/
public void addPes(Pes pes) {
if(getPid() != pes.getPid() // 自分のデータではない
|| getCodecType() == null) { // 初期化が済んでいない
return; // スキップしておく。
}
// 新規データなのでとりあえず追加しておく。
videoPesList.add(pes);
if(pes.isPayloadUnitStart()) { // データpacketの開始位置の場合
AdaptationField field = pes.getAdaptationField();
if(pes.isAdaptationFieldExist() && field != null) { // adaptationFieldが存在している場合
if(field.getRandomAccessIndicator() == 1) { // ランダムアクセスが許可されているデータの場合(キーフレームであるということ)
keyPesList.add(pes); // キーフレームのpesデータなので、リストにいれておく。
}
}
}
if(pes.hasPts() && lastDataPts < pes.getPts().getPts()) {
lastDataPts = pes.getPts().getPts();
}
}
/**
* 終端データのpts値
* @return
*/
public long getLastDataPts() {
if(keyPesList.size() == 0) {
return lastDataPts;
}
Pes lastKeyFramePes = keyPesList.get(keyPesList.size() - 1);
return lastKeyFramePes.getPts().getPts();
}
/**
* 先頭データのpts値
*/
public long getFirstDataPts() {
if(keyPesList.size() == 0) {
return lastDataPts;
}
Pes firstKeyFramePes = keyPesList.get(0);
return firstKeyFramePes.getPts().getPts();
}
/**
* 2番目のデータのpts値(次のkeyFrame的な感じ)
* @return
*/
public long getSecondDataPts() {
if(keyPesList.size() <= 1) {
return -1;
}
Pes secondKeyFramePes = keyPesList.get(1);
return secondKeyFramePes.getPts().getPts();
}
/**
* 先頭を取り出す
* @return
*/
public Pes shift() {
if(videoPesList.size() == 0) {
return null;
}
Pes targetPes = videoPesList.remove(0);
// keyPesと一致するpesがある場合は撤去しておく
if(keyPesList.contains(targetPes)) {
keyPesList.remove(targetPes);
}
return targetPes;
}
/**
* 先頭に追加
* データを取り出したけど、使わなかったときに戻す感じ
*/
public void unshift(Pes pes) {
if(pes == null) {
return;
}
// 相手がkeyFrameとなりうるpesの場合は・・・keyFrame側にも追加する必要がある。
videoPesList.add(0, pes);
if(pes.isPayloadUnitStart()) { // データpacketの開始位置の場合
AdaptationField field = pes.getAdaptationField();
if(pes.isAdaptationFieldExist() && field != null) { // adaptationFieldが存在している場合
if(field.getRandomAccessIndicator() == 1) { // ランダムアクセスが許可されているデータの場合(キーフレームであるということ)
keyPesList.add(0, pes); // キーフレームのpesデータなので、リストにいれておく。
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder data = new StringBuilder();
data.append("videoDataList:").append(videoPesList.size());
return data.toString();
}
}