mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-22 11:12:36 +01:00
Work on mp4
This commit is contained in:
parent
c060baaed5
commit
22bce82ce1
@ -5,19 +5,18 @@ namespace Nikse.SubtitleEdit.Core.Cea608
|
||||
{
|
||||
public static class GetCcDataHelper
|
||||
{
|
||||
public static List<CcData> GetCcData(Stream fs, uint startPos, ulong size)
|
||||
public static List<CcData> GetCcData(Stream fs, ulong startPos, ulong size)
|
||||
{
|
||||
var fieldData = new List<CcData>();
|
||||
for (var i = startPos; i < startPos + size - 5; i++)
|
||||
{
|
||||
var buffer = new byte[4];
|
||||
fs.Seek(i, SeekOrigin.Begin);
|
||||
fs.Seek((long)i, SeekOrigin.Begin);
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
var nalSize = GetUInt32(buffer, 0);
|
||||
var flag = fs.ReadByte();
|
||||
if (IsRbspNalUnitType(flag & 0x1F))
|
||||
{
|
||||
//parseCCDataFromSEI(getSEIData(raw, i + 5, i + nalSize + 3), fieldData);
|
||||
var seiData = GetSeiData(fs, i + 5, i + nalSize + 3);
|
||||
ParseCcDataFromSei(seiData, fieldData);
|
||||
}
|
||||
@ -33,11 +32,11 @@ namespace Nikse.SubtitleEdit.Core.Cea608
|
||||
return unitType == 0x06;
|
||||
}
|
||||
|
||||
private static byte[] GetSeiData(Stream fs, uint startPos, uint endPos)
|
||||
public static byte[] GetSeiData(Stream fs, ulong startPos, ulong endPos)
|
||||
{
|
||||
var data = new List<byte>();
|
||||
var buffer = new byte[endPos - startPos];
|
||||
fs.Seek(startPos, SeekOrigin.Begin);
|
||||
fs.Seek((long)startPos, SeekOrigin.Begin);
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
|
||||
for (var x = startPos; x < endPos; x++)
|
||||
@ -59,7 +58,7 @@ namespace Nikse.SubtitleEdit.Core.Cea608
|
||||
return data.ToArray();
|
||||
}
|
||||
|
||||
private static void ParseCcDataFromSei(byte[] buffer, List<CcData> fieldData)
|
||||
public static void ParseCcDataFromSei(byte[] buffer, List<CcData> fieldData)
|
||||
{
|
||||
var x = 0;
|
||||
while (x < buffer.Length)
|
||||
|
@ -6,22 +6,27 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Nikse.SubtitleEdit.Core.Cea608;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
{
|
||||
public class Stbl : Box
|
||||
{
|
||||
public Stsd Stsd { get; set; }
|
||||
public List<SubPicture> SubPictures;
|
||||
public ulong StszSampleCount;
|
||||
public ulong TimeScale { get; set; }
|
||||
private readonly Mdia _mdia;
|
||||
public List<uint> SampleSizes;
|
||||
public List<uint> Discardable;
|
||||
public List<uint> Ssts { get; set; }
|
||||
public List<SampleToChunkMap> Stsc { get; set; }
|
||||
public List<ulong> ChunkOffsets;
|
||||
public List<Paragraph> Paragraphs;
|
||||
public List<Paragraph> GetParagraphs() => Paragraphs;
|
||||
|
||||
private List<Cea608.CcData> _cea608CcData = new List<Cea608.CcData>();
|
||||
|
||||
public Stbl(Stream fs, ulong maximumLength, ulong timeScale, string handlerType, Mdia mdia)
|
||||
{
|
||||
TimeScale = timeScale;
|
||||
@ -30,6 +35,7 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
Ssts = new List<uint>();
|
||||
Stsc = new List<SampleToChunkMap>();
|
||||
SampleSizes = new List<uint>();
|
||||
Discardable = new List<uint>();
|
||||
ChunkOffsets = new List<ulong>();
|
||||
SubPictures = new List<SubPicture>();
|
||||
while (fs.Position < (long)maximumLength)
|
||||
@ -39,9 +45,13 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
return;
|
||||
}
|
||||
|
||||
if (Name == "stco") // 32-bit - chunk offset
|
||||
if (Name == "stsd") // Sample Description Box
|
||||
{
|
||||
if (handlerType != "vide" && handlerType != "soun")
|
||||
Stsd = new Stsd(fs, Position);
|
||||
}
|
||||
else if (Name == "stco") // 32-bit - chunk offset
|
||||
{
|
||||
if (handlerType != "soun")
|
||||
{
|
||||
Buffer = new byte[Size - 4];
|
||||
fs.Read(Buffer, 0, Buffer.Length);
|
||||
@ -57,7 +67,7 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
}
|
||||
else if (Name == "co64") // 64-bit
|
||||
{
|
||||
if (handlerType != "vide" && handlerType != "soun")
|
||||
if (handlerType != "soun")
|
||||
{
|
||||
Buffer = new byte[Size - 4];
|
||||
fs.Read(Buffer, 0, Buffer.Length);
|
||||
@ -81,10 +91,11 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
StszSampleCount = numberOfSampleSizes;
|
||||
for (var i = 0; i < numberOfSampleSizes; i++)
|
||||
{
|
||||
if (12 + i * 4 + 4 < Buffer.Length)
|
||||
if (17 + i * 4 < Buffer.Length)
|
||||
{
|
||||
var sampleSize = GetUInt(12 + i * 4);
|
||||
SampleSizes.Add(sampleSize);
|
||||
Discardable.Add(Buffer[17 + i * 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,13 +138,13 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
fs.Seek((long)Position, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
if (handlerType != "vide" && handlerType != "soun")
|
||||
if (handlerType != "soun")
|
||||
{
|
||||
Paragraphs = GetParagraphs(fs, handlerType == "subp");
|
||||
Paragraphs = GetParagraphs(fs, handlerType);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Paragraph> GetParagraphs(Stream fs, bool subtitlePicture)
|
||||
private List<Paragraph> GetParagraphs(Stream fs, string handlerType)
|
||||
{
|
||||
var paragraphs = new List<Paragraph>();
|
||||
uint samplesPerChunk = 1;
|
||||
@ -166,38 +177,67 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
{
|
||||
p.StartTime.TotalSeconds = before;
|
||||
|
||||
fs.Seek((long)chunkOffset, SeekOrigin.Begin);
|
||||
var buffer = new byte[2];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
var textSize = (uint)GetWord(buffer, 0);
|
||||
if (textSize == 0 && samplesPerChunk > 1)
|
||||
if (handlerType == "vide")
|
||||
{
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
textSize = (uint)GetWord(buffer, 0);
|
||||
}
|
||||
|
||||
if (textSize > 0)
|
||||
{
|
||||
if (subtitlePicture) // VobSub created with Mp4Box
|
||||
if (Discardable[index] == 1)
|
||||
{
|
||||
if (textSize > 100)
|
||||
{
|
||||
buffer = new byte[textSize + 2];
|
||||
fs.Seek((long)chunkOffset, SeekOrigin.Begin);
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
SubPictures.Add(new SubPicture(buffer)); // TODO: Where is palette?
|
||||
paragraphs.Add(p);
|
||||
}
|
||||
//TODO: cea 608 or 708 cc? What is the content?
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = new byte[textSize];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
p.Text = GetString(buffer, 0, (int)textSize).TrimEnd();
|
||||
}
|
||||
else if (handlerType == "clcp" && Stsd?.Name == "c608")
|
||||
{
|
||||
//TODO: decode cea 608... but what is the content?
|
||||
|
||||
if (_mdia.IsClosedCaption)
|
||||
//var ccData = GetCcDataHelper.GetCcData(fs, chunkOffset + 4, sampleSize);
|
||||
|
||||
//var fieldData = new List<CcData>();
|
||||
//// var seiData = GetCcDataHelper.GetSeiData(fs, chunkOffset , chunkOffset + sampleSize);
|
||||
|
||||
//var seiData = new byte[sampleSize];
|
||||
//fs.Seek((long)chunkOffset, SeekOrigin.Begin);
|
||||
//fs.Read(seiData, 0, seiData.Length);
|
||||
//GetCcDataHelper.ParseCcDataFromSei(seiData, fieldData);
|
||||
|
||||
//if (fieldData.Count > 0)
|
||||
//{
|
||||
// _cea608CcData.AddRange(fieldData);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
fs.Seek((long)chunkOffset, SeekOrigin.Begin);
|
||||
var buffer = new byte[2];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
var textSize = (uint)GetWord(buffer, 0);
|
||||
if (textSize == 0 && samplesPerChunk > 1)
|
||||
{
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
textSize = (uint)GetWord(buffer, 0);
|
||||
}
|
||||
|
||||
if (textSize > 0)
|
||||
{
|
||||
if (handlerType == "subp") // VobSub created with Mp4Box
|
||||
{
|
||||
p.Text = MakeScenaristText(buffer);
|
||||
if (textSize > 100)
|
||||
{
|
||||
buffer = new byte[textSize + 2];
|
||||
fs.Seek((long)chunkOffset, SeekOrigin.Begin);
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
SubPictures.Add(new SubPicture(buffer)); // TODO: Where is palette?
|
||||
paragraphs.Add(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = new byte[textSize];
|
||||
fs.Read(buffer, 0, buffer.Length);
|
||||
p.Text = GetString(buffer, 0, (int)textSize).TrimEnd();
|
||||
|
||||
if (_mdia.IsClosedCaption)
|
||||
{
|
||||
p.Text = MakeScenaristText(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
src/libse/ContainerFormats/Mp4/Boxes/Stsd.cs
Normal file
27
src/libse/ContainerFormats/Mp4/Boxes/Stsd.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System.IO;
|
||||
|
||||
namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
||||
{
|
||||
public class Stsd : Box
|
||||
{
|
||||
public uint NumberOfEntries { get; set; }
|
||||
public Stsd(Stream fs, ulong maximumLength)
|
||||
{
|
||||
Position = (ulong)fs.Position;
|
||||
|
||||
Buffer = new byte[8];
|
||||
fs.Read(Buffer, 0, Buffer.Length);
|
||||
NumberOfEntries = GetUInt(4);
|
||||
|
||||
while (fs.Position < (long)maximumLength)
|
||||
{
|
||||
if (!InitializeSizeAndName(fs))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
fs.Seek((long)Position, SeekOrigin.Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user