158 lines
5.2 KiB
C++
158 lines
5.2 KiB
C++
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <mist/ts_packet.h> //TS support
|
|
#include <mist/dtsc.h> //DTSC support
|
|
#include <mist/mp4.h> //For initdata conversion
|
|
#define VIDEO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["video"]["fpks"].asInt())
|
|
#define AUDIO_SCALING ( 27000000.0 / (double)DTSCStream.metadata["audio"]["rate"].asInt())
|
|
|
|
int main(){
|
|
char charBuffer[1024 * 10];
|
|
unsigned int charCount;
|
|
std::string StrData;
|
|
std::string ToPack;
|
|
std::string DTMIData;
|
|
TS::Packet PackData;
|
|
DTSC::Stream DTSCStream;
|
|
int PacketNumber = 0;
|
|
long long unsigned int TimeStamp = 0;
|
|
int ThisNaluSize;
|
|
char VideoCounter = 0;
|
|
char AudioCounter = 0;
|
|
bool WritePesHeader;
|
|
bool IsKeyFrame;
|
|
bool FirstKeyFrame = true;
|
|
bool FirstIDRInKeyFrame;
|
|
MP4::AVCC avccbox;
|
|
bool haveAvcc = false;
|
|
|
|
while (std::cin.good()){
|
|
if (DTSCStream.parsePacket(StrData)){
|
|
if ( !haveAvcc){
|
|
avccbox.setPayload(DTSCStream.metadata["video"]["init"].asString());
|
|
haveAvcc = true;
|
|
}
|
|
if (DTSCStream.lastType() == DTSC::VIDEO){
|
|
DTMIData = DTSCStream.lastData();
|
|
if (DTSCStream.getPacket(0).isMember("keyframe")){
|
|
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);
|
|
}
|
|
WritePesHeader = true;
|
|
while (ToPack.size()){
|
|
if ((PacketNumber % 42) == 0){
|
|
PackData.DefaultPAT();
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PackData.DefaultPMT();
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PacketNumber += 2;
|
|
}
|
|
PackData.Clear();
|
|
PackData.PID(0x100);
|
|
PackData.ContinuityCounter(VideoCounter);
|
|
VideoCounter++;
|
|
if (WritePesHeader){
|
|
PackData.UnitStart(1);
|
|
if (IsKeyFrame){
|
|
PackData.RandomAccess(1);
|
|
PackData.PCR(TimeStamp);
|
|
}else{
|
|
PackData.AdaptationField(1);
|
|
}
|
|
PackData.AddStuffing(184 - (20 + ToPack.size()));
|
|
PackData.PESVideoLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90);
|
|
WritePesHeader = false;
|
|
}else{
|
|
PackData.AdaptationField(1);
|
|
PackData.AddStuffing(184 - (ToPack.size()));
|
|
}
|
|
PackData.FillFree(ToPack);
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PacketNumber++;
|
|
}
|
|
}else if (DTSCStream.lastType() == DTSC::AUDIO){
|
|
WritePesHeader = true;
|
|
DTMIData = DTSCStream.lastData();
|
|
ToPack = TS::GetAudioHeader(DTMIData.size(), DTSCStream.metadata["audio"]["init"].asString());
|
|
ToPack += DTMIData;
|
|
while (ToPack.size()){
|
|
if ((PacketNumber % 42) == 0){
|
|
PackData.DefaultPAT();
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PackData.DefaultPMT();
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PacketNumber += 2;
|
|
}
|
|
PackData.Clear();
|
|
PackData.PID(0x101);
|
|
PackData.ContinuityCounter(AudioCounter);
|
|
AudioCounter++;
|
|
if (WritePesHeader){
|
|
PackData.UnitStart(1);
|
|
PackData.AddStuffing(184 - (14 + ToPack.size()));
|
|
PackData.PESAudioLeadIn(ToPack.size(), DTSCStream.getPacket(0)["time"].asInt() * 90);
|
|
WritePesHeader = false;
|
|
}else{
|
|
PackData.AdaptationField(1);
|
|
PackData.AddStuffing(184 - ToPack.size());
|
|
}
|
|
PackData.FillFree(ToPack);
|
|
std::cout.write(PackData.ToString(), 188);
|
|
PacketNumber++;
|
|
}
|
|
}
|
|
}else{
|
|
std::cin.read(charBuffer, 1024 * 10);
|
|
charCount = std::cin.gcount();
|
|
StrData.append(charBuffer, charCount);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|