mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
Open multistream files with ffdshow
This commit is contained in:
@@ -177,10 +177,10 @@ namespace CUETools.ALACEnc
|
|||||||
if (output_file == null)
|
if (output_file == null)
|
||||||
output_file = Path.ChangeExtension(input_file, "m4a");
|
output_file = Path.ChangeExtension(input_file, "m4a");
|
||||||
settings.PCM = audioSource.PCM;
|
settings.PCM = audioSource.PCM;
|
||||||
Codecs.ALAC.AudioEncoder alac = new Codecs.ALAC.AudioEncoder((output_file == "-" || output_file == "nul") ? "" : output_file,
|
Codecs.ALAC.AudioEncoder alac = new Codecs.ALAC.AudioEncoder(settings,
|
||||||
|
(output_file == "-" || output_file == "nul") ? "" : output_file,
|
||||||
output_file == "-" ? Console.OpenStandardOutput() :
|
output_file == "-" ? Console.OpenStandardOutput() :
|
||||||
output_file == "nul" ? new NullStream() : null,
|
output_file == "nul" ? new NullStream() : null);
|
||||||
settings);
|
|
||||||
alac.FinalSampleCount = audioSource.Length;
|
alac.FinalSampleCount = audioSource.Length;
|
||||||
IAudioDest audioDest = alac;
|
IAudioDest audioDest = alac;
|
||||||
AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
|
AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
|
||||||
|
|||||||
@@ -7,13 +7,12 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
{
|
{
|
||||||
public class AudioDecoder : IAudioSource
|
public class AudioDecoder : IAudioSource
|
||||||
{
|
{
|
||||||
public unsafe AudioDecoder(string path, Stream IO, ushort pid)
|
public unsafe AudioDecoder(string path, Stream IO, int pid)
|
||||||
: this(path, IO)
|
: this(new DecoderSettings() { StreamId = pid }, path, IO)
|
||||||
{
|
{
|
||||||
settings.Pid = pid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe AudioDecoder(string path, Stream IO)
|
public unsafe AudioDecoder(DecoderSettings settings, string path, Stream IO)
|
||||||
{
|
{
|
||||||
_path = path;
|
_path = path;
|
||||||
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
||||||
@@ -23,10 +22,10 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
_samplePos = 0;
|
_samplePos = 0;
|
||||||
_sampleLen = -1;
|
_sampleLen = -1;
|
||||||
demux_ts_packets(null, 0);
|
demux_ts_packets(null, 0);
|
||||||
settings = new DecoderSettings();
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAudioDecoderSettings Settings => settings;
|
public IAudioDecoderSettings Settings => m_settings;
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
@@ -88,11 +87,11 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
get {
|
get {
|
||||||
if (chosenStream == null)
|
if (chosenStream == null)
|
||||||
{
|
{
|
||||||
if (settings.Pid.HasValue)
|
if (m_settings.StreamId.HasValue)
|
||||||
{
|
{
|
||||||
if (streams.ContainsKey(settings.Pid.Value))
|
if (streams.ContainsKey((ushort)m_settings.StreamId.Value))
|
||||||
{
|
{
|
||||||
var s = streams[settings.Pid.Value];
|
var s = streams[(ushort)m_settings.StreamId.Value];
|
||||||
if (s.is_opened)
|
if (s.is_opened)
|
||||||
{
|
{
|
||||||
chosenStream = s;
|
chosenStream = s;
|
||||||
@@ -103,14 +102,14 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
return chosenStream.pcm;
|
return chosenStream.pcm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Exception("Pid can be " +
|
throw new Exception("StreamId can be " +
|
||||||
string.Join(", ", (new List<ushort>(streams.Keys)).FindAll(pid => streams[pid].is_opened).ConvertAll(pid => pid.ToString()).ToArray()));
|
string.Join(", ", (new List<ushort>(streams.Keys)).FindAll(pid => streams[pid].is_opened).ConvertAll(pid => pid.ToString()).ToArray()));
|
||||||
}
|
}
|
||||||
if (settings.Stream.HasValue)
|
if (m_settings.Stream.HasValue)
|
||||||
{
|
{
|
||||||
foreach (var s in streams)
|
foreach (var s in streams)
|
||||||
{
|
{
|
||||||
if (s.Value.is_opened && s.Value.streamId == settings.Stream.Value)
|
if (s.Value.is_opened && s.Value.streamId == m_settings.Stream.Value)
|
||||||
{
|
{
|
||||||
chosenStream = s.Value;
|
chosenStream = s.Value;
|
||||||
if (chosenStream.pcm == null)
|
if (chosenStream.pcm == null)
|
||||||
@@ -124,7 +123,7 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
string.Join(", ", (new List<TsStream>(streams.Values)).FindAll(s => s.is_opened).ConvertAll(s => s.streamId.ToString()).ToArray()));
|
string.Join(", ", (new List<TsStream>(streams.Values)).FindAll(s => s.is_opened).ConvertAll(s => s.streamId.ToString()).ToArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception("multiple streams present, please specify Pid or Stream");
|
throw new Exception("multiple streams present, please specify StreamId or Stream");
|
||||||
}
|
}
|
||||||
return chosenStream.pcm;
|
return chosenStream.pcm;
|
||||||
}
|
}
|
||||||
@@ -735,6 +734,6 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
int demuxer_channel;
|
int demuxer_channel;
|
||||||
TsStream chosenStream;
|
TsStream chosenStream;
|
||||||
long _samplePos, _sampleLen;
|
long _samplePos, _sampleLen;
|
||||||
DecoderSettings settings;
|
DecoderSettings m_settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
public int? Stream { get; set; }
|
public int? Stream { get; set; }
|
||||||
|
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public ushort? Pid { get; set; }
|
public int? StreamId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,13 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
public class MPLSDecoder : IAudioSource
|
public class MPLSDecoder : IAudioSource
|
||||||
{
|
{
|
||||||
public unsafe MPLSDecoder(string path, Stream IO, ushort pid)
|
public unsafe MPLSDecoder(string path, Stream IO, ushort pid)
|
||||||
: this(path, IO)
|
: this(new MPLS.DecoderSettings() { StreamId = pid }, path, IO)
|
||||||
{
|
{
|
||||||
settings.Pid = pid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe MPLSDecoder(string path, Stream IO)
|
public unsafe MPLSDecoder(MPLS.DecoderSettings settings, string path, Stream IO)
|
||||||
{
|
{
|
||||||
settings = new DecoderSettings();
|
m_settings = settings;
|
||||||
_path = path;
|
_path = path;
|
||||||
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
_IO = IO != null ? IO : new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 0x10000);
|
||||||
int length = (int)_IO.Length;
|
int length = (int)_IO.Length;
|
||||||
@@ -36,33 +35,33 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
void openEntries()
|
void openEntries()
|
||||||
{
|
{
|
||||||
readers = new List<AudioDecoder>();
|
readers = new List<AudioDecoder>();
|
||||||
var pids = new List<ushort>();
|
var pids = new List<int>();
|
||||||
foreach (var item in hdr_m.play_item)
|
foreach (var item in hdr_m.play_item)
|
||||||
foreach (var audio in item.audio)
|
foreach (var audio in item.audio)
|
||||||
{
|
{
|
||||||
if (audio.coding_type != 0x80 /* LPCM */) continue;
|
if (audio.coding_type != 0x80 /* LPCM */) continue;
|
||||||
pids.Add(audio.pid);
|
pids.Add(audio.pid);
|
||||||
}
|
}
|
||||||
ushort chosenPid;
|
int chosenPid;
|
||||||
if (settings.Pid.HasValue)
|
if (m_settings.StreamId.HasValue)
|
||||||
{
|
{
|
||||||
if (!pids.Contains(settings.Pid.Value))
|
if (!pids.Contains(m_settings.StreamId.Value))
|
||||||
throw new Exception("Pid can be " +
|
throw new Exception("StreamId can be " +
|
||||||
string.Join(", ", pids.ConvertAll(pid => pid.ToString()).ToArray()));
|
string.Join(", ", pids.ConvertAll(pid => pid.ToString()).ToArray()));
|
||||||
chosenPid = settings.Pid.Value;
|
chosenPid = m_settings.StreamId.Value;
|
||||||
}
|
}
|
||||||
else if (settings.Stream.HasValue)
|
else if (m_settings.Stream.HasValue)
|
||||||
{
|
{
|
||||||
if (settings.Stream.Value < 0 || settings.Stream.Value >= pids.Count)
|
if (m_settings.Stream.Value < 0 || m_settings.Stream.Value >= pids.Count)
|
||||||
throw new Exception("Stream can be 0.." + (pids.Count - 1).ToString());
|
throw new Exception("Stream can be 0.." + (pids.Count - 1).ToString());
|
||||||
chosenPid = pids[settings.Stream.Value];
|
chosenPid = pids[m_settings.Stream.Value];
|
||||||
}
|
}
|
||||||
else throw new Exception("multiple streams present, please specify Pid or Stream");
|
else throw new Exception("multiple streams present, please specify StreamId or Stream");
|
||||||
foreach (var item in hdr_m.play_item)
|
foreach (var item in hdr_m.play_item)
|
||||||
foreach (var audio in item.audio)
|
foreach (var audio in item.audio)
|
||||||
{
|
{
|
||||||
if (audio.coding_type != 0x80 /* LPCM */) continue;
|
if (audio.coding_type != 0x80 /* LPCM */) continue;
|
||||||
if (settings.IgnoreShortItems && item.out_time - item.in_time < shortItemDuration) continue;
|
if (m_settings.IgnoreShortItems && item.out_time - item.in_time < shortItemDuration) continue;
|
||||||
if (audio.pid == chosenPid)
|
if (audio.pid == chosenPid)
|
||||||
{
|
{
|
||||||
var parent = Directory.GetParent(System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(_path)));
|
var parent = Directory.GetParent(System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(_path)));
|
||||||
@@ -277,7 +276,7 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
return mark;
|
return mark;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAudioDecoderSettings Settings => settings;
|
public IAudioDecoderSettings Settings => m_settings;
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
@@ -308,7 +307,7 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
{
|
{
|
||||||
if (item.num_audio == 0) continue;
|
if (item.num_audio == 0) continue;
|
||||||
uint item_duration = item.out_time - item.in_time;
|
uint item_duration = item.out_time - item.in_time;
|
||||||
if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
if (m_settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
||||||
totalLength += item_duration;
|
totalLength += item_duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,13 +402,13 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
ushort mark_item = hdr_m.play_mark[i].play_item_ref;
|
ushort mark_item = hdr_m.play_mark[i].play_item_ref;
|
||||||
uint item_in_time = hdr_m.play_item[mark_item].in_time;
|
uint item_in_time = hdr_m.play_item[mark_item].in_time;
|
||||||
uint item_out_time = hdr_m.play_item[mark_item].out_time;
|
uint item_out_time = hdr_m.play_item[mark_item].out_time;
|
||||||
if (settings.IgnoreShortItems && item_out_time - item_in_time < shortItemDuration) continue;
|
if (m_settings.IgnoreShortItems && item_out_time - item_in_time < shortItemDuration) continue;
|
||||||
uint item_offset = 0;
|
uint item_offset = 0;
|
||||||
for (int j = 0; j < mark_item; j++)
|
for (int j = 0; j < mark_item; j++)
|
||||||
{
|
{
|
||||||
if (hdr_m.play_item[j].num_audio == 0) continue;
|
if (hdr_m.play_item[j].num_audio == 0) continue;
|
||||||
uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
||||||
if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
if (m_settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
||||||
item_offset += item_duration;
|
item_offset += item_duration;
|
||||||
}
|
}
|
||||||
res.Add(hdr_m.play_mark[i].time - item_in_time + item_offset);
|
res.Add(hdr_m.play_mark[i].time - item_in_time + item_offset);
|
||||||
@@ -419,7 +418,7 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
{
|
{
|
||||||
if (hdr_m.play_item[j].num_audio == 0) continue;
|
if (hdr_m.play_item[j].num_audio == 0) continue;
|
||||||
uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
uint item_duration = hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
||||||
if (settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
if (m_settings.IgnoreShortItems && item_duration < shortItemDuration) continue;
|
||||||
end_offset += hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
end_offset += hdr_m.play_item[j].out_time - hdr_m.play_item[j].in_time;
|
||||||
}
|
}
|
||||||
res.Add(end_offset);
|
res.Add(end_offset);
|
||||||
@@ -439,7 +438,7 @@ namespace CUETools.Codecs.BDLPCM
|
|||||||
List<AudioDecoder> readers;
|
List<AudioDecoder> readers;
|
||||||
AudioDecoder currentReader;
|
AudioDecoder currentReader;
|
||||||
MPLSHeader hdr_m;
|
MPLSHeader hdr_m;
|
||||||
DecoderSettings settings;
|
MPLS.DecoderSettings m_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MPLSPlaylistMark
|
public struct MPLSPlaylistMark
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ namespace CUETools.Codecs.MPLS
|
|||||||
public int? Stream { get; set; }
|
public int? Stream { get; set; }
|
||||||
|
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public ushort? Pid { get; set; }
|
public int? StreamId { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj" />
|
<ProjectReference Include="..\CUETools.Codecs\CUETools.Codecs.csproj" />
|
||||||
<ProjectReference Include="..\ThirdParty\MAC_SDK\Source\Projects\VS2017\MACLibDll\MACLibDll.vcxproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -5,6 +5,24 @@ using FFmpeg.AutoGen;
|
|||||||
|
|
||||||
namespace CUETools.Codecs.ffmpegdll
|
namespace CUETools.Codecs.ffmpegdll
|
||||||
{
|
{
|
||||||
|
internal static class FFmpegHelper
|
||||||
|
{
|
||||||
|
public static unsafe string av_strerror(int error)
|
||||||
|
{
|
||||||
|
var bufferSize = 1024;
|
||||||
|
var buffer = stackalloc byte[bufferSize];
|
||||||
|
ffmpeg.av_strerror(error, buffer, (ulong)bufferSize);
|
||||||
|
var message = Marshal.PtrToStringAnsi((IntPtr)buffer);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ThrowExceptionIfError(this int error)
|
||||||
|
{
|
||||||
|
if (error < 0) throw new ApplicationException(av_strerror(error));
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public unsafe class AudioDecoder : IAudioSource, IDisposable
|
public unsafe class AudioDecoder : IAudioSource, IDisposable
|
||||||
{
|
{
|
||||||
private static void RegisterLibrariesSearchPath(string path)
|
private static void RegisterLibrariesSearchPath(string path)
|
||||||
@@ -126,13 +144,13 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
if ((ret = ffmpeg.avformat_open_input(&new_fmt_ctx, null, fmt, null)) < 0)
|
if ((ret = ffmpeg.avformat_open_input(&new_fmt_ctx, null, fmt, null)) < 0)
|
||||||
{
|
{
|
||||||
ffmpeg.avformat_free_context(new_fmt_ctx);
|
ffmpeg.avformat_free_context(new_fmt_ctx);
|
||||||
throw new Exception("Cannot open input file");
|
ret.ThrowExceptionIfError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = ffmpeg.avformat_find_stream_info(new_fmt_ctx, null)) < 0)
|
if ((ret = ffmpeg.avformat_find_stream_info(new_fmt_ctx, null)) < 0)
|
||||||
{
|
{
|
||||||
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
||||||
throw new Exception("Cannot find stream information");
|
ret.ThrowExceptionIfError();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FINDBESTSTREAM
|
#if FINDBESTSTREAM
|
||||||
@@ -141,38 +159,51 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
||||||
throw new Exception("Cannot find an audio stream in the input file");
|
ret.ThrowExceptionIfError();
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (new_fmt_ctx->nb_streams != 1)
|
|
||||||
{
|
|
||||||
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
|
||||||
throw new Exception("More than one stream");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
int matching_stream = -1;
|
||||||
|
int matching_streams = 0;
|
||||||
|
for (int i = 0; i < (int)new_fmt_ctx->nb_streams; i++)
|
||||||
|
{
|
||||||
|
AVStream* stream_i = new_fmt_ctx->streams[i];
|
||||||
|
if (stream_i->codecpar->codec_type == AVMediaType.AVMEDIA_TYPE_AUDIO &&
|
||||||
|
(settings.StreamId == 0 || settings.StreamId == stream_i->id))
|
||||||
|
{
|
||||||
|
matching_stream = i;
|
||||||
|
matching_streams++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int audio_stream_index = 0; // ret
|
if (matching_streams == 0)
|
||||||
|
{
|
||||||
|
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
||||||
|
throw new Exception("No matching streams");
|
||||||
|
}
|
||||||
|
if (matching_streams != 1)
|
||||||
|
{
|
||||||
|
ffmpeg.avformat_close_input(&new_fmt_ctx);
|
||||||
|
throw new Exception("More than one stream matches");
|
||||||
|
}
|
||||||
|
|
||||||
if (new_fmt_ctx->streams[audio_stream_index]->duration > 0)
|
stream = new_fmt_ctx->streams[matching_stream];
|
||||||
_sampleCount = new_fmt_ctx->streams[audio_stream_index]->duration;
|
// Duration is unreliable for most codecs.
|
||||||
else
|
//if (stream->duration > 0)
|
||||||
|
// _sampleCount = stream->duration;
|
||||||
|
//else
|
||||||
_sampleCount = -1;
|
_sampleCount = -1;
|
||||||
|
|
||||||
int bps = new_fmt_ctx->streams[audio_stream_index]->codecpar->bits_per_raw_sample != 0 ?
|
int bps = stream->codecpar->bits_per_raw_sample != 0 ?
|
||||||
new_fmt_ctx->streams[audio_stream_index]->codecpar->bits_per_raw_sample :
|
stream->codecpar->bits_per_raw_sample :
|
||||||
new_fmt_ctx->streams[audio_stream_index]->codecpar->bits_per_coded_sample;
|
stream->codecpar->bits_per_coded_sample;
|
||||||
int channels = new_fmt_ctx->streams[audio_stream_index]->codecpar->channels;
|
int channels = stream->codecpar->channels;
|
||||||
int sample_rate = new_fmt_ctx->streams[audio_stream_index]->codecpar->sample_rate;
|
int sample_rate = stream->codecpar->sample_rate;
|
||||||
ulong channel_layout = new_fmt_ctx->streams[audio_stream_index]->codecpar->channel_layout;
|
ulong channel_layout = stream->codecpar->channel_layout;
|
||||||
pcm = new AudioPCMConfig(bps, channels, sample_rate, (AudioPCMConfig.SpeakerConfig)channel_layout);
|
pcm = new AudioPCMConfig(bps, channels, sample_rate, (AudioPCMConfig.SpeakerConfig)channel_layout);
|
||||||
|
|
||||||
// ret = ffmpeg.av_read_frame(new_fmt_ctx, pkt);
|
|
||||||
|
|
||||||
fmt_ctx = new_fmt_ctx;
|
fmt_ctx = new_fmt_ctx;
|
||||||
|
|
||||||
//m_stream.Seek(0, SeekOrigin.Begin);
|
codec = ffmpeg.avcodec_find_decoder(stream->codecpar->codec_id);
|
||||||
|
|
||||||
codec = ffmpeg.avcodec_find_decoder(fmt_ctx->streams[audio_stream_index]->codecpar->codec_id);
|
|
||||||
if (codec == null)
|
if (codec == null)
|
||||||
throw new Exception("Codec not found");
|
throw new Exception("Codec not found");
|
||||||
|
|
||||||
@@ -180,7 +211,7 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
if (c == null)
|
if (c == null)
|
||||||
throw new Exception("Could not allocate audio codec context");
|
throw new Exception("Could not allocate audio codec context");
|
||||||
// ffmpeg.av_opt_set_int(c, "refcounted_frames", 1, 0);
|
// ffmpeg.av_opt_set_int(c, "refcounted_frames", 1, 0);
|
||||||
ffmpeg.avcodec_parameters_to_context(c, fmt_ctx->streams[audio_stream_index]->codecpar);
|
ffmpeg.avcodec_parameters_to_context(c, stream->codecpar);
|
||||||
|
|
||||||
c->request_sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S32;
|
c->request_sample_fmt = AVSampleFormat.AV_SAMPLE_FMT_S32;
|
||||||
|
|
||||||
@@ -305,7 +336,7 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
return;
|
return;
|
||||||
if (ret != ffmpeg.AVERROR(ffmpeg.EAGAIN))
|
if (ret != ffmpeg.AVERROR(ffmpeg.EAGAIN))
|
||||||
{
|
{
|
||||||
if (ret < 0) throw new Exception("Error during decoding");
|
if (ret < 0) ret.ThrowExceptionIfError();
|
||||||
m_decoded_frame_offset = 0;
|
m_decoded_frame_offset = 0;
|
||||||
m_decoded_frame_size = decoded_frame->nb_samples;
|
m_decoded_frame_size = decoded_frame->nb_samples;
|
||||||
return;
|
return;
|
||||||
@@ -315,15 +346,12 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
{
|
{
|
||||||
if (ret == ffmpeg.AVERROR_EOF)
|
if (ret == ffmpeg.AVERROR_EOF)
|
||||||
return;
|
return;
|
||||||
byte* buf = stackalloc byte[256];
|
ret.ThrowExceptionIfError();
|
||||||
ffmpeg.av_strerror(ret, buf, 256);
|
|
||||||
throw new Exception("Error while parsing: " + Marshal.PtrToStringAnsi((IntPtr)buf));
|
|
||||||
}
|
}
|
||||||
if (pkt->size != 0)
|
if (pkt->size != 0 && pkt->stream_index == stream->index)
|
||||||
{
|
{
|
||||||
/* send the packet with the compressed data to the decoder */
|
/* send the packet with the compressed data to the decoder */
|
||||||
ret = ffmpeg.avcodec_send_packet(c, pkt);
|
ffmpeg.avcodec_send_packet(c, pkt).ThrowExceptionIfError();
|
||||||
if (ret < 0) throw new Exception("Error submitting the packet to the decoder");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -402,6 +430,7 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
AVCodec* codec;
|
AVCodec* codec;
|
||||||
AVCodecContext* c;
|
AVCodecContext* c;
|
||||||
AVFormatContext* fmt_ctx;
|
AVFormatContext* fmt_ctx;
|
||||||
|
AVStream* stream;
|
||||||
|
|
||||||
avio_alloc_context_read_packet m_read_packet_callback;
|
avio_alloc_context_read_packet m_read_packet_callback;
|
||||||
avio_alloc_context_seek m_seek_callback;
|
avio_alloc_context_seek m_seek_callback;
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
|
|
||||||
public abstract string Format { get; }
|
public abstract string Format { get; }
|
||||||
|
|
||||||
|
public int StreamId { get; set; }
|
||||||
|
|
||||||
// [DisplayName("Version")]
|
// [DisplayName("Version")]
|
||||||
// [Description("Library version")]
|
// [Description("Library version")]
|
||||||
// public string Version => Marshal.PtrToStringAnsi(MACLibDll.GetVersionString());
|
// public string Version => Marshal.PtrToStringAnsi(MACLibDll.GetVersionString());
|
||||||
@@ -100,4 +102,13 @@ namespace CUETools.Codecs.ffmpegdll
|
|||||||
this.Init();
|
this.Init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public class MpegTSDecoderSettings : DecoderSettings, IAudioDecoderSettings
|
||||||
|
{
|
||||||
|
public override string Extension => "m2ts";
|
||||||
|
public override string Format => "mpegts";
|
||||||
|
public MpegTSDecoderSettings()
|
||||||
|
{
|
||||||
|
this.Init();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,7 @@ namespace CUETools.Converter
|
|||||||
Console.Error.WriteLine("Options:");
|
Console.Error.WriteLine("Options:");
|
||||||
Console.Error.WriteLine();
|
Console.Error.WriteLine();
|
||||||
Console.Error.WriteLine(" --decoder <name> Use non-default decoder.");
|
Console.Error.WriteLine(" --decoder <name> Use non-default decoder.");
|
||||||
|
Console.Error.WriteLine(" --decoder-option <name> <value>");
|
||||||
Console.Error.WriteLine(" --encoder <name> Use non-default encoder.");
|
Console.Error.WriteLine(" --encoder <name> Use non-default encoder.");
|
||||||
Console.Error.WriteLine(" --encoder-format <ext> Use encoder format different from file extension.");
|
Console.Error.WriteLine(" --encoder-format <ext> Use encoder format different from file extension.");
|
||||||
Console.Error.WriteLine(" --lossy Use lossy encoder/mode.");
|
Console.Error.WriteLine(" --lossy Use lossy encoder/mode.");
|
||||||
@@ -34,7 +35,7 @@ namespace CUETools.Converter
|
|||||||
(lossless ? fmt.encoderLossless : fmt.encoderLossy);
|
(lossless ? fmt.encoderLossless : fmt.encoderLossy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IAudioSource GetAudioSource(CUEToolsCodecsConfig config, string path, string chosenDecoder, bool ignore_chunk_sizes)
|
public static IAudioSource GetAudioSource(CUEToolsCodecsConfig config, string path, string chosenDecoder, bool ignore_chunk_sizes, Dictionary<string, string> decoderOptions)
|
||||||
{
|
{
|
||||||
if (path == "-")
|
if (path == "-")
|
||||||
return new Codecs.WAV.AudioDecoder(new Codecs.WAV.DecoderSettings() { IgnoreChunkSizes = true }, "", Console.OpenStandardInput());
|
return new Codecs.WAV.AudioDecoder(new Codecs.WAV.DecoderSettings() { IgnoreChunkSizes = true }, "", Console.OpenStandardInput());
|
||||||
@@ -52,6 +53,14 @@ namespace CUETools.Converter
|
|||||||
if (decoder == null)
|
if (decoder == null)
|
||||||
throw new Exception("Unsupported audio type: " + path);
|
throw new Exception("Unsupported audio type: " + path);
|
||||||
var settings = decoder.Settings.Clone();
|
var settings = decoder.Settings.Clone();
|
||||||
|
foreach (var decOpt in decoderOptions)
|
||||||
|
{
|
||||||
|
var property = TypeDescriptor.GetProperties(settings).Find(decOpt.Key, true);
|
||||||
|
if (property == null)
|
||||||
|
throw new Exception($"{settings.Name} {settings.Extension} decoder settings object (of type {settings.GetType().FullName}) doesn't have a property named {decOpt.Key}.");
|
||||||
|
property.SetValue(settings,
|
||||||
|
TypeDescriptor.GetConverter(property.PropertyType).ConvertFromString(decOpt.Value));
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
object src = Activator.CreateInstance(decoder.Settings.DecoderType, settings, path, IO);
|
object src = Activator.CreateInstance(decoder.Settings.DecoderType, settings, path, IO);
|
||||||
@@ -149,18 +158,7 @@ namespace CUETools.Converter
|
|||||||
try
|
try
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
audioSource = Program.GetAudioSource(config, sourceFile, decoderName, ignore_chunk_sizes);
|
audioSource = Program.GetAudioSource(config, sourceFile, decoderName, ignore_chunk_sizes, decoderOptions);
|
||||||
foreach (var decOpt in decoderOptions)
|
|
||||||
{
|
|
||||||
var decoderSettings = audioSource.Settings;
|
|
||||||
if (decoderSettings == null)
|
|
||||||
throw new Exception(String.Format("{0} doesn't have any properties.", audioSource.GetType().Name));
|
|
||||||
var property = TypeDescriptor.GetProperties(decoderSettings).Find(decOpt.Key, true);
|
|
||||||
if (property == null)
|
|
||||||
throw new Exception(String.Format("{0} doesn't have a property named {1}.", audioSource.GetType().Name, decOpt.Key));
|
|
||||||
property.SetValue(decoderSettings,
|
|
||||||
TypeDescriptor.GetConverter(property.PropertyType).ConvertFromString(decOpt.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
|
AudioBuffer buff = new AudioBuffer(audioSource, 0x10000);
|
||||||
Console.Error.WriteLine("Filename : {0}", sourceFile);
|
Console.Error.WriteLine("Filename : {0}", sourceFile);
|
||||||
|
|||||||
@@ -130,11 +130,13 @@ namespace CUETools.eac3to
|
|||||||
TimeSpan duration;
|
TimeSpan duration;
|
||||||
TagLib.UserDefined.AdditionalFileTypes.Config = config;
|
TagLib.UserDefined.AdditionalFileTypes.Config = config;
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
try
|
try
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
var mpls = new MPLSDecoder(sourceFile, null);
|
var mpls = new MPLSDecoder(new Codecs.MPLS.DecoderSettings(), sourceFile, null);
|
||||||
audioSource = mpls;
|
audioSource = mpls;
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
int frameRate = 0;
|
int frameRate = 0;
|
||||||
@@ -314,8 +316,8 @@ namespace CUETools.eac3to
|
|||||||
throw new Exception("Video extraction not supported.");
|
throw new Exception("Video extraction not supported.");
|
||||||
if (stream - chapterStreams - videos.Count > audios.Count)
|
if (stream - chapterStreams - videos.Count > audios.Count)
|
||||||
throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream));
|
throw new Exception(string.Format("The source file doesn't contain a track with the number {0}.", stream));
|
||||||
ushort pid = audios[stream - chapterStreams - videos.Count - 1].pid;
|
int pid = audios[stream - chapterStreams - videos.Count - 1].pid;
|
||||||
(audioSource.Settings as Codecs.MPLS.DecoderSettings).Pid = pid;
|
(audioSource.Settings as Codecs.MPLS.DecoderSettings).StreamId = pid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,9 +369,9 @@ namespace CUETools.eac3to
|
|||||||
object o = null;
|
object o = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, "", Console.OpenStandardOutput(), settings) :
|
o = destFile == "-" ? Activator.CreateInstance(settings.EncoderType, settings, "", Console.OpenStandardOutput()) :
|
||||||
destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, "", new NullStream(), settings) :
|
destFile == "nul" ? Activator.CreateInstance(settings.EncoderType, settings, "", new NullStream()) :
|
||||||
Activator.CreateInstance(settings.EncoderType, destFile, settings);
|
Activator.CreateInstance(settings.EncoderType, settings, destFile, null);
|
||||||
}
|
}
|
||||||
catch (System.Reflection.TargetInvocationException ex)
|
catch (System.Reflection.TargetInvocationException ex)
|
||||||
{
|
{
|
||||||
@@ -418,12 +420,14 @@ namespace CUETools.eac3to
|
|||||||
totalElapsed
|
totalElapsed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
#if !DEBUG
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (audioSource != null) audioSource.Close();
|
if (audioSource != null) audioSource.Close();
|
||||||
if (audioDest != null) audioDest.Delete();
|
if (audioDest != null) audioDest.Delete();
|
||||||
throw ex;
|
throw ex;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
audioSource.Close();
|
audioSource.Close();
|
||||||
audioDest.Close();
|
audioDest.Close();
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace BluTools
|
|||||||
if (playlists != null)
|
if (playlists != null)
|
||||||
foreach (var playlist in playlists)
|
foreach (var playlist in playlists)
|
||||||
{
|
{
|
||||||
var title = new MPLSDecoder(playlist, null);
|
var title = new MPLSDecoder(new CUETools.Codecs.MPLS.DecoderSettings(), playlist, null);
|
||||||
if (filterDups)
|
if (filterDups)
|
||||||
{
|
{
|
||||||
if (titleSets.Exists(title2 =>
|
if (titleSets.Exists(title2 =>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace CUETools.TestCodecs
|
|||||||
|
|
||||||
AudioEncoder.Vendor = "CUETools";
|
AudioEncoder.Vendor = "CUETools";
|
||||||
|
|
||||||
target = new Codecs.ALAC.AudioEncoder("alacwriter1.m4a", null, new Codecs.ALAC.EncoderSettings() { PCM = buff.PCM });
|
target = new Codecs.ALAC.AudioEncoder(new Codecs.ALAC.EncoderSettings() { PCM = buff.PCM }, "alacwriter1.m4a", null);
|
||||||
target.Settings.Padding = 1;
|
target.Settings.Padding = 1;
|
||||||
target.CreationTime = DateTime.Parse("15 Aug 1976");
|
target.CreationTime = DateTime.Parse("15 Aug 1976");
|
||||||
target.FinalSampleCount = buff.Length;
|
target.FinalSampleCount = buff.Length;
|
||||||
@@ -89,7 +89,7 @@ namespace CUETools.TestCodecs
|
|||||||
target.Close();
|
target.Close();
|
||||||
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter1.m4a"), "alacwriter1.m4a doesn't match.");
|
CollectionAssert.AreEqual(File.ReadAllBytes("alac.m4a"), File.ReadAllBytes("alacwriter1.m4a"), "alacwriter1.m4a doesn't match.");
|
||||||
|
|
||||||
target = new Codecs.ALAC.AudioEncoder("alacwriter0.m4a", null, new Codecs.ALAC.EncoderSettings() { PCM = buff.PCM });
|
target = new Codecs.ALAC.AudioEncoder(new Codecs.ALAC.EncoderSettings() { PCM = buff.PCM }, "alacwriter0.m4a", null);
|
||||||
target.Settings.Padding = 1;
|
target.Settings.Padding = 1;
|
||||||
target.CreationTime = DateTime.Parse("15 Aug 1976");
|
target.CreationTime = DateTime.Parse("15 Aug 1976");
|
||||||
target.Write(buff);
|
target.Write(buff);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace CUETools.TestCodecs
|
|||||||
AudioBuffer buff = Codecs.WAV.AudioDecoder.ReadAllSamples(new Codecs.WAV.DecoderSettings(), "test.wav");
|
AudioBuffer buff = Codecs.WAV.AudioDecoder.ReadAllSamples(new Codecs.WAV.DecoderSettings(), "test.wav");
|
||||||
CUETools.Codecs.libFLAC.Encoder target;
|
CUETools.Codecs.libFLAC.Encoder target;
|
||||||
|
|
||||||
target = new CUETools.Codecs.libFLAC.Encoder("flacwriter2.flac", new CUETools.Codecs.libFLAC.EncoderSettings() { PCM = buff.PCM, EncoderMode = "7" });
|
target = new CUETools.Codecs.libFLAC.Encoder(new CUETools.Codecs.libFLAC.EncoderSettings() { PCM = buff.PCM, EncoderMode = "7" }, "flacwriter2.flac");
|
||||||
target.Settings.Padding = 1;
|
target.Settings.Padding = 1;
|
||||||
target.Settings.BlockSize = 32;
|
target.Settings.BlockSize = 32;
|
||||||
//target.Vendor = "CUETools";
|
//target.Vendor = "CUETools";
|
||||||
@@ -49,7 +49,7 @@ namespace CUETools.TestCodecs
|
|||||||
[TestMethod()]
|
[TestMethod()]
|
||||||
public void SeekTest()
|
public void SeekTest()
|
||||||
{
|
{
|
||||||
var r = new CUETools.Codecs.libFLAC.Reader("test.flac", null);
|
var r = new CUETools.Codecs.libFLAC.Reader(new Codecs.libFLAC.DecoderSettings(), "test.flac", null);
|
||||||
var buff1 = new AudioBuffer(r, 16536);
|
var buff1 = new AudioBuffer(r, 16536);
|
||||||
var buff2 = new AudioBuffer(r, 16536);
|
var buff2 = new AudioBuffer(r, 16536);
|
||||||
Assert.AreEqual(0, r.Position);
|
Assert.AreEqual(0, r.Position);
|
||||||
|
|||||||
Reference in New Issue
Block a user