All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tv.hd3g.fflauncher.about.FFAboutCodec Maven / Gradle / Ivy

/*
 * This file is part of fflauncher.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * Copyright (C) hdsdi3g for hd3g.tv 2018
 *
 */
package tv.hd3g.fflauncher.about;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import tv.hd3g.fflauncher.UnknownFormatException;

public class FFAboutCodec {

	private static final String CAN_T_PARSE_LINE = "Can't parse line: \"";

	static List parse(final List lines) {
		return lines.stream()
				.map(String::trim)
				.dropWhile(line -> line.startsWith("-") == false && line.endsWith("-") == false)
				.filter(line -> line.startsWith("-") == false && line.endsWith("-") == false)
				.map(FFAboutCodec::new)
				.toList();
	}

	public enum CodecType {
		VIDEO,
		AUDIO,
		SUBTITLE,
		DATA;
	}

	public final boolean decodingSupported;
	public final boolean encodingSupported;
	public final CodecType type;
	public final boolean intraFrameOnly;
	public final boolean lossyCompression;
	public final boolean losslessCompression;

	public final Set encoders;
	public final Set decoders;

	/**
	 * Like "dpx"
	 */
	public final String name;

	/**
	 * Like "DPX (Digital Picture Exchange) image"
	 */
	public final String longName;

	private static CodecType letterToCodecType(final String line, final char letter) {
		if (letter == 'V') {
			return CodecType.VIDEO;
		} else if (letter == 'A') {
			return CodecType.AUDIO;
		} else if (letter == 'S') {
			return CodecType.SUBTITLE;
		} else if (letter == 'D') {
			return CodecType.DATA;
		} else {
			throw new UnknownFormatException(CAN_T_PARSE_LINE + line + "\" (missing codec type)");
		}
	}

	private static void negativeToOutOfBoundException(final int value, final String text) {
		if (value == -1) {
			throw new IndexOutOfBoundsException(text);
		}
	}

	FFAboutCodec(final String line) {
		final var lineBlocs = line.split(" ");

		if (lineBlocs.length < 3) {
			throw new UnknownFormatException(CAN_T_PARSE_LINE + line + "\"");
		}

		/**
		 * Parse "codec type zone"
		 */

		decodingSupported = lineBlocs[0].charAt(0) == 'D';
		encodingSupported = lineBlocs[0].charAt(1) == 'E';
		type = letterToCodecType(line, lineBlocs[0].charAt(2));
		intraFrameOnly = lineBlocs[0].charAt(3) == 'I';
		lossyCompression = lineBlocs[0].charAt(4) == 'L';
		losslessCompression = lineBlocs[0].charAt(5) == 'S';

		if (lineBlocs[0].substring(3).chars().noneMatch(i -> (i == 'I' || i == 'L' || i == 'S' || i == '.'))) {
			throw new UnknownFormatException(CAN_T_PARSE_LINE + line + "\" (invalid ends for codec type)");
		}

		name = lineBlocs[1].trim();

		/**
		 * Like "Dirac (decoders: dirac libschroedinger ) (encoders: vc2 libschroedinger )"
		 */
		final var raw_long_name = Arrays.stream(lineBlocs)
				.filter(lb -> lb.trim().equals("") == false)
				.skip(2)
				.collect(Collectors.joining(" "));

		final var parDecoders = "(decoders:";
		final var decoders_tag_pos = raw_long_name.indexOf(parDecoders);
		final var encoders_tag_pos = raw_long_name.indexOf("(encoders:");

		if (decoders_tag_pos > -1 || encoders_tag_pos > -1) {
			if (decoders_tag_pos > -1) {
				final var decoders_tag_end_pos = raw_long_name.indexOf(')', decoders_tag_pos);
				negativeToOutOfBoundException(decoders_tag_end_pos, "Can't found \")\" in \"" + raw_long_name + "\"");
				decoders = Collections.unmodifiableSet(Arrays.stream(raw_long_name.substring(decoders_tag_pos
																							 + parDecoders.length(),
						decoders_tag_end_pos).trim().split(" ")).distinct().collect(Collectors.toSet()));
			} else {
				decoders = Collections.emptySet();
			}

			if (encoders_tag_pos > -1) {
				final var encoders_tag_end_pos = raw_long_name.indexOf(')', encoders_tag_pos);
				negativeToOutOfBoundException(encoders_tag_end_pos, "Can't found \")\" in \"" + raw_long_name + "\"");
				encoders = Collections.unmodifiableSet(Arrays.stream(raw_long_name.substring(encoders_tag_pos
																							 + parDecoders.length(),
						encoders_tag_end_pos).trim().split(" ")).distinct().collect(Collectors.toSet()));
			} else {
				encoders = Collections.emptySet();
			}

			longName = extractLongnameFromRawLongName(raw_long_name, decoders_tag_pos, encoders_tag_pos);
		} else {
			encoders = Collections.emptySet();
			decoders = Collections.emptySet();
			longName = raw_long_name;
		}
	}

	private static String extractLongnameFromRawLongName(final String raw_long_name,
														 final int decoders_tag_pos,
														 final int encoders_tag_pos) {
		if (decoders_tag_pos > -1 && encoders_tag_pos > -1) {
			return raw_long_name.substring(0, Math.min(decoders_tag_pos - 1, encoders_tag_pos - 1));
		} else if (decoders_tag_pos > -1) {
			return raw_long_name.substring(0, decoders_tag_pos - 1);
		} else {
			return raw_long_name.substring(0, encoders_tag_pos - 1);
		}
	}

	@Override
	public String toString() {
		final var sb = new StringBuilder();

		sb.append(longName);
		sb.append(" [");
		sb.append(name);
		sb.append("] ");

		sb.append(type.toString().toLowerCase());

		if (decodingSupported && encodingSupported) {
			sb.append(" encoding and decoding supported");
		} else if (decodingSupported) {
			sb.append(" decoding only supported");
		} else {
			sb.append(" encoding only supported");
		}

		if (intraFrameOnly) {
			sb.append(", intra frame-only codec");
		}
		if (lossyCompression) {
			sb.append(", lossy compression");
		}
		if (losslessCompression) {
			sb.append(", lossless compression");
		}

		return sb.toString();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy