Uniform structure and documentation for the converters.

This commit is contained in:
Erik Zandvliet 2013-03-28 15:43:06 +01:00
parent 1e2f1602f8
commit 18c4015940
4 changed files with 117 additions and 135 deletions

View file

@ -15,10 +15,11 @@
#include <mist/amf.h> //AMF support #include <mist/amf.h> //AMF support
#include <mist/config.h> #include <mist/config.h>
/// Holds all code that converts filetypes to/from DTSC. ///\brief Holds everything unique to converters.
namespace Converters { namespace Converters {
/// Reads DTSC from STDIN, outputs FLV to STDOUT. ///\brief Converts DTSC from stdin to FLV on stdout.
///\return The return code for the converter.
int DTSC2FLV(){ int DTSC2FLV(){
FLV::Tag FLV_out; // Temporary storage for outgoing FLV data. FLV::Tag FLV_out; // Temporary storage for outgoing FLV data.
DTSC::Stream Strm; DTSC::Stream Strm;

View file

@ -10,149 +10,127 @@
#include <mist/ts_packet.h> //TS support #include <mist/ts_packet.h> //TS support
#include <mist/dtsc.h> //DTSC support #include <mist/dtsc.h> //DTSC support
#include <mist/mp4.h> //For initdata conversion #include <mist/mp4.h> //For initdata conversion
#define VIDEO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["video"]["fpks"].asInt()) #include <mist/config.h>
#define AUDIO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["audio"]["rate"].asInt())
int main(){ ///\brief Holds everything unique to converters.
char charBuffer[1024 * 10]; namespace Converters {
unsigned int charCount; ///\brief Converts DTSC from stdin to TS on stdout.
std::string StrData; ///\return The return code for the converter.
std::string ToPack; int DTSC2TS(){
std::string DTMIData; char charBuffer[1024 * 10];
TS::Packet PackData; unsigned int charCount;
DTSC::Stream DTSCStream; std::string StrData;
int PacketNumber = 0; TS::Packet PackData;
long long unsigned int TimeStamp = 0; DTSC::Stream Strm;
int ThisNaluSize; int PacketNumber = 0;
char VideoCounter = 0; long long unsigned int TimeStamp = 0;
char AudioCounter = 0; int ThisNaluSize;
bool WritePesHeader; char VideoCounter = 0;
bool IsKeyFrame; char AudioCounter = 0;
bool FirstKeyFrame = true; bool WritePesHeader;
bool FirstIDRInKeyFrame; bool IsKeyFrame;
MP4::AVCC avccbox; MP4::AVCC avccbox;
bool haveAvcc = false; bool haveAvcc = false;
std::stringstream TSBuf;
while (std::cin.good()){
if (DTSCStream.parsePacket(StrData)){ while (std::cin.good()){
if ( !haveAvcc){ if (Strm.parsePacket(StrData)){
avccbox.setPayload(DTSCStream.metadata["video"]["init"].asString()); if (Strm.lastType() == DTSC::PAUSEMARK){
haveAvcc = true; TSBuf.flush();
} if (TSBuf.str().size()){
if (DTSCStream.lastType() == DTSC::VIDEO){ std::cout << TSBuf.str();
DTMIData = DTSCStream.lastData(); TSBuf.str("");
if (DTSCStream.getPacket(0).isMember("keyframe")){ PacketNumber = 0;
IsKeyFrame = true;
FirstIDRInKeyFrame = true;
}else{
IsKeyFrame = false;
FirstKeyFrame = false;
}
if (IsKeyFrame){
TimeStamp = (DTSCStream.getPacket(0)["time"].asInt() * 27000);
}
int TSType;
bool FirstPic = true;
while (DTMIData.size()){
ThisNaluSize = (DTMIData[0] << 24) + (DTMIData[1] << 16) + (DTMIData[2] << 8) + DTMIData[3];
DTMIData.erase(0, 4); //Erase the first four characters;
TSType = (int)DTMIData[0] & 0x1F;
if ( !(TSType == 0x09)){
if (TSType == 0x05){
if (FirstPic){
ToPack += avccbox.asAnnexB();
FirstPic = false;
}
if (IsKeyFrame){
if ( !FirstKeyFrame && FirstIDRInKeyFrame){
ToPack.append(TS::NalHeader, 4);
FirstIDRInKeyFrame = false;
}else{
ToPack.append(TS::ShortNalHeader, 3);
}
}
}else if (TSType == 0x01){
if (FirstPic){
ToPack.append(TS::NalHeader, 4);
FirstPic = false;
}else{
ToPack.append(TS::ShortNalHeader, 3);
}
}else{
ToPack.append(TS::NalHeader, 4);
}
ToPack.append(DTMIData, 0, ThisNaluSize);
} }
DTMIData.erase(0, ThisNaluSize); TSBuf.str("");
} }
WritePesHeader = true; if ( !haveAvcc){
while (ToPack.size()){ avccbox.setPayload(Strm.metadata["video"]["init"].asString());
if ((PacketNumber % 42) == 0){ haveAvcc = true;
}
if (Strm.lastType() == DTSC::VIDEO || Strm.lastType() == DTSC::AUDIO){
Socket::Buffer ToPack;
//write PAT and PMT TS packets
if (PacketNumber == 0){
PackData.DefaultPAT(); PackData.DefaultPAT();
std::cout.write(PackData.ToString(), 188); TSBuf.write(PackData.ToString(), 188);
PackData.DefaultPMT(); PackData.DefaultPMT();
std::cout.write(PackData.ToString(), 188); TSBuf.write(PackData.ToString(), 188);
PacketNumber += 2; PacketNumber += 2;
} }
PackData.Clear();
PackData.PID(0x100); int PIDno = 0;
PackData.ContinuityCounter(VideoCounter); char * ContCounter = 0;
VideoCounter++; if (Strm.lastType() == DTSC::VIDEO){
if (WritePesHeader){ IsKeyFrame = Strm.getPacket(0).isMember("keyframe");
PackData.UnitStart(1);
if (IsKeyFrame){ if (IsKeyFrame){
PackData.RandomAccess(1); TimeStamp = (Strm.getPacket(0)["time"].asInt() * 27000);
PackData.PCR(TimeStamp);
}else{
PackData.AdaptationField(1);
} }
PackData.AddStuffing(184 - (20 + ToPack.size())); ToPack.append(avccbox.asAnnexB());
PackData.PESVideoLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90); while (Strm.lastData().size()){
WritePesHeader = false; ThisNaluSize = (Strm.lastData()[0] << 24) + (Strm.lastData()[1] << 16) + (Strm.lastData()[2] << 8) + Strm.lastData()[3];
}else{ Strm.lastData().replace(0, 4, TS::NalHeader, 4);
PackData.AdaptationField(1); if (ThisNaluSize + 4 == Strm.lastData().size()){
PackData.AddStuffing(184 - (ToPack.size())); ToPack.append(Strm.lastData());
} break;
PackData.FillFree(ToPack); }else{
std::cout.write(PackData.ToString(), 188); ToPack.append(Strm.lastData().c_str(), ThisNaluSize + 4);
PacketNumber++; Strm.lastData().erase(0, ThisNaluSize + 4);
} }
}else if (DTSCStream.lastType() == DTSC::AUDIO){ }
WritePesHeader = true; ToPack.prepend(TS::Packet::getPESVideoLeadIn(0ul, Strm.getPacket(0)["time"].asInt() * 90));
DTMIData = DTSCStream.lastData(); PIDno = 0x100;
ToPack = TS::GetAudioHeader(DTMIData.size(), DTSCStream.metadata["audio"]["init"].asString()); ContCounter = &VideoCounter;
ToPack += DTMIData; }else if (Strm.lastType() == DTSC::AUDIO){
while (ToPack.size()){ ToPack.append(TS::GetAudioHeader(Strm.lastData().size(), Strm.metadata["audio"]["init"].asString()));
if ((PacketNumber % 42) == 0){ ToPack.append(Strm.lastData());
PackData.DefaultPAT(); ToPack.prepend(TS::Packet::getPESAudioLeadIn(ToPack.bytes(1073741824ul), Strm.getPacket(0)["time"].asInt() * 90));
std::cout.write(PackData.ToString(), 188); PIDno = 0x101;
PackData.DefaultPMT(); ContCounter = &AudioCounter;
std::cout.write(PackData.ToString(), 188);
PacketNumber += 2;
} }
//initial packet
PackData.Clear(); PackData.Clear();
PackData.PID(0x101); PackData.PID(PIDno);
PackData.ContinuityCounter(AudioCounter); PackData.ContinuityCounter(( *ContCounter)++);
AudioCounter++; PackData.UnitStart(1);
if (WritePesHeader){ if (IsKeyFrame){
PackData.UnitStart(1); PackData.RandomAccess(1);
PackData.AddStuffing(184 - (14 + ToPack.size())); PackData.PCR(TimeStamp);
PackData.PESAudioLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90);
WritePesHeader = false;
}else{
PackData.AdaptationField(1);
PackData.AddStuffing(184 - ToPack.size());
} }
PackData.FillFree(ToPack); unsigned int toSend = PackData.AddStuffing(ToPack.bytes(184));
std::cout.write(PackData.ToString(), 188); std::string gonnaSend = ToPack.remove(toSend);
PackData.FillFree(gonnaSend);
TSBuf.write(PackData.ToString(), 188);
PacketNumber++; PacketNumber++;
//rest of packets
while (ToPack.size()){
PackData.Clear();
PackData.PID(PIDno);
PackData.ContinuityCounter(( *ContCounter)++);
toSend = PackData.AddStuffing(ToPack.bytes(184));
gonnaSend = ToPack.remove(toSend);
PackData.FillFree(gonnaSend);
TSBuf.write(PackData.ToString(), 188);
PacketNumber++;
}
} }
}else{
std::cin.read(charBuffer, 1024 * 10);
charCount = std::cin.gcount();
StrData.append(charBuffer, charCount);
} }
}else{
std::cin.read(charBuffer, 1024 * 10);
charCount = std::cin.gcount();
StrData.append(charBuffer, charCount);
} }
return 0;
} }
return 0; }
///\brief Entry point for DTSC2TS, simply calls Converters::DTSC2TS().
int main(int argc, char* argv[]){
Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
conf.parseArgs(argc, argv);
return Converters::DTSC2TS();
} }

View file

@ -6,10 +6,12 @@
#include <mist/json.h> #include <mist/json.h>
#include <mist/config.h> #include <mist/config.h>
/// Holds all code that converts filetypes to/from to DTSC. ///\brief Holds everything unique to converters.
namespace Converters { namespace Converters {
/// Reads an DTSC file and attempts to fix the metadata in it. ///\brief Reads a DTSC file and attempts to fix the metadata in it.
///\param conf The current configuration of the program.
///\return The return code for the fixed program.
int DTSCFix(Util::Config & conf){ int DTSCFix(Util::Config & conf){
DTSC::File F(conf.getString("filename")); DTSC::File F(conf.getString("filename"));
JSON::Value oriheader = F.getFirstMeta(); JSON::Value oriheader = F.getFirstMeta();
@ -124,7 +126,7 @@ namespace Converters {
} }
/// Entry point for FLV2DTSC, simply calls Converters::FLV2DTSC(). /// Entry point for DTSCFix, simply calls Converters::DTSCFix().
int main(int argc, char ** argv){ int main(int argc, char ** argv){
Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
conf.addOption("filename", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the file to attempt to fix.\"}")); conf.addOption("filename", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the file to attempt to fix.\"}"));

View file

@ -16,10 +16,11 @@
#include <mist/amf.h> #include <mist/amf.h>
#include <mist/config.h> #include <mist/config.h>
/// Holds all code that converts filetypes to/from to DTSC. ///\brief Holds everything unique to converters.
namespace Converters { namespace Converters {
/// Reads FLV from STDIN, outputs DTSC to STDOUT. ///\brief Converts FLV from stdin to DTSC on stdout.
///\return The return code for the converter.
int FLV2DTSC(){ int FLV2DTSC(){
FLV::Tag FLV_in; // Temporary storage for incoming FLV data. FLV::Tag FLV_in; // Temporary storage for incoming FLV data.
JSON::Value meta_out; // Storage for outgoing header data. JSON::Value meta_out; // Storage for outgoing header data.
@ -75,7 +76,7 @@ namespace Converters {
} }
/// Entry point for FLV2DTSC, simply calls Converters::FLV2DTSC(). ///\brief Entry point for FLV2DTSC, simply calls Converters::FLV2DTSC().
int main(int argc, char ** argv){ int main(int argc, char ** argv){
Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION); Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
conf.parseArgs(argc, argv); conf.parseArgs(argc, argv);