MP3 codec support in more protocols.

This commit is contained in:
ozzay 2014-08-11 16:46:19 +02:00 committed by Thulinma
parent aedf06d3ef
commit 286d6cba5c
3 changed files with 92 additions and 41 deletions

View file

@ -21,6 +21,7 @@ namespace Mist {
capa["socket"] = "http_progressive_mp4";
capa["codecs"][0u][0u].append("H264");
capa["codecs"][0u][1u].append("AAC");
capa["codecs"][0u][1u].append("MP3");
capa["methods"][0u]["handler"] = "http";
capa["methods"][0u]["type"] = "html5/video/mp4";
capa["methods"][0u]["priority"] = 8ll;
@ -113,6 +114,9 @@ namespace Mist {
if (myMeta.tracks[*it].codec == "AAC"){
ase.setCodec("mp4a");
ase.setDataReferenceIndex(1);
}else if (myMeta.tracks[*it].codec == "MP3"){
ase.setCodec("mp4a");
ase.setDataReferenceIndex(1);
}
ase.setSampleRate(myMeta.tracks[*it].rate);
ase.setChannelCount(myMeta.tracks[*it].channels);
@ -121,23 +125,37 @@ namespace Mist {
MP4::ESDS esdsBox;
//outputting these values first, so malloc isn't called as often.
esdsBox.setESHeaderStartCodes(myMeta.tracks[*it].init);
esdsBox.setSLValue(2);
esdsBox.setESDescriptorTypeLength(32+myMeta.tracks[*it].init.size());
if (myMeta.tracks[*it].codec == "MP3"){
esdsBox.setESHeaderStartCodes("\002");
esdsBox.setConfigDescriptorTypeLength(1);
esdsBox.setSLConfigExtendedDescriptorTypeTag(0);
esdsBox.setSLDescriptorTypeLength(0);
esdsBox.setESDescriptorTypeLength(27);
esdsBox.setSLConfigDescriptorTypeTag(0);
esdsBox.setDecoderDescriptorTypeTag(0x06);
esdsBox.setSLValue(0);
//esdsBox.setBufferSize(0);
esdsBox.setDecoderConfigDescriptorTypeLength(13);
esdsBox.setByteObjectTypeID(0x6b);
}else{
//AAC
esdsBox.setESHeaderStartCodes(myMeta.tracks[*it].init);
esdsBox.setConfigDescriptorTypeLength(myMeta.tracks[*it].init.size());
esdsBox.setSLConfigExtendedDescriptorTypeTag(0x808080);
esdsBox.setSLDescriptorTypeLength(1);
esdsBox.setESDescriptorTypeLength(32+myMeta.tracks[*it].init.size());
esdsBox.setSLConfigDescriptorTypeTag(0x6);
esdsBox.setSLValue(2);
esdsBox.setDecoderConfigDescriptorTypeLength(18 + myMeta.tracks[*it].init.size());
esdsBox.setByteObjectTypeID(0x40);
}
esdsBox.setESID(2);
esdsBox.setStreamPriority(0);
esdsBox.setDecoderConfigDescriptorTypeLength(18 + myMeta.tracks[*it].init.size());
esdsBox.setByteObjectTypeID(0x40);
esdsBox.setStreamType(5);
esdsBox.setReservedFlag(1);
esdsBox.setBufferSize(1250000);
esdsBox.setMaximumBitRate(10000000);
esdsBox.setAverageBitRate(myMeta.tracks[*it].bps * 8);
esdsBox.setConfigDescriptorTypeLength(5);
esdsBox.setSLConfigDescriptorTypeTag(0x6);
esdsBox.setSLConfigExtendedDescriptorTypeTag(0x808080);
esdsBox.setSLDescriptorTypeLength(1);
esdsBox.setBufferSize(1250000);
ase.setCodecBox(esdsBox);
stsdBox.setEntry(ase,0);
}

View file

@ -8,23 +8,6 @@ namespace Mist {
AudioCounter = 0;
VideoCounter = 0;
std::string tracks = config->getString("tracks");
unsigned int currTrack = 0;
//loop over tracks, add any found track IDs to selectedTracks
if (tracks != ""){
for (unsigned int i = 0; i < tracks.size(); ++i){
if (tracks[i] >= '0' && tracks[i] <= '9'){
currTrack = currTrack*10 + (tracks[i] - '0');
}else{
if (currTrack > 0){
selectedTracks.insert(currTrack);
}
currTrack = 0;
}
}
if (currTrack > 0){
selectedTracks.insert(currTrack);
}
}
streamName = config->getString("streamname");
parseData = true;
wantRequest = false;
@ -48,6 +31,7 @@ namespace Mist {
capa["optional"]["tracks"]["option"] = "--tracks";
capa["codecs"][0u][0u].append("H264");
capa["codecs"][0u][1u].append("AAC");
capa["codecs"][0u][1u].append("MP3");
cfg->addOption("streamname",
JSON::fromString("{\"arg\":\"string\",\"short\":\"s\",\"long\":\"stream\",\"help\":\"The name of the stream that this connector will transmit.\"}"));
cfg->addOption("tracks",
@ -91,8 +75,12 @@ namespace Mist {
}
ContCounter = &VideoCounter;
}else if (myMeta.tracks[currentPacket.getTrackId()].type == "audio"){
ToPack.append(TS::Packet::getPESAudioLeadIn(7+dataLen, currentPacket.getTime() * 90));
ToPack.append(TS::GetAudioHeader(dataLen, myMeta.tracks[currentPacket.getTrackId()].init));
if (myMeta.tracks[currentPacket.getTrackId()].codec == "AAC"){
ToPack.append(TS::Packet::getPESAudioLeadIn(7+dataLen, currentPacket.getTime() * 90));
ToPack.append(TS::GetAudioHeader(dataLen, myMeta.tracks[currentPacket.getTrackId()].init));
}else{
ToPack.append(TS::Packet::getPESAudioLeadIn(dataLen, currentPacket.getTime() * 90));
}
ToPack.append(dataPointer, dataLen);
ContCounter = &AudioCounter;
}
@ -101,17 +89,11 @@ namespace Mist {
//send TS packets
while (ToPack.size()){
PackData.Clear();
/// \todo Update according to sendHeader()'s generated data.
//0x100 - 1 + currentPacket.getTrackId()
if (myMeta.tracks[currentPacket.getTrackId()].type == "video"){
PackData.PID(0x100);
}else{
PackData.PID(0x101);
}
PackData.PID(0x100 - 1 + currentPacket.getTrackId());
PackData.ContinuityCounter((*ContCounter)++);
if (first){
PackData.UnitStart(1);
if (IsKeyFrame){
if (IsKeyFrame || myMeta.tracks[currentPacket.getTrackId()].type == "audio"){
PackData.RandomAccess(1);
PackData.PCR(currentPacket.getTime() * 27000);
}
@ -124,11 +106,60 @@ namespace Mist {
}
}
///this function generates the PMT packet
std::string OutTS::createPMT(){
//0x02 = table ID = 2 = PMT
//0xB017 = section syntax(1) = 1, 0(1)=0, reserved(2) = 3, section_len(12) = 23
//0x0001 = ProgNo = 1
//0xC1 = reserved(2) = 3, version(5)=0, curr_next_indi(1) = 1
//0x00 = section_number = 0
//0x00 = last_section_no = 0
//0xE100 = reserved(3) = 7, PCR_PID(13) = 0x100
//0xF000 = reserved(4) = 15, proginfolen = 0
//0x1B = streamtype = 27 = H264
//0xE100 = reserved(3) = 7, elem_ID(13) = 0x100
//0xF000 = reserved(4) = 15, es_info_len = 0
//0x0F = streamtype = 15 = audio with ADTS transport syntax
//0xE101 = reserved(3) = 7, elem_ID(13) = 0x101
//0xF000 = reserved(4) = 15, es_info_len = 0
//0x2F44B99B = CRC32
TS::ProgramMappingTable PMT;
PMT.PID(4096);
PMT.setTableId(2);
PMT.setSectionLength(0xB017);
PMT.setProgramNumber(1);
PMT.setVersionNumber(0);
PMT.setCurrentNextIndicator(0);
PMT.setSectionNumber(0);
PMT.setLastSectionNumber(0);
PMT.setPCRPID(0x100 + (*(selectedTracks.begin())) - 1);
PMT.setProgramInfoLength(0);
short id = 0;
//for all selected tracks
for (std::set<long unsigned int>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
if (myMeta.tracks[*it].codec == "H264"){
PMT.setStreamType(0x1B,id);
}else if (myMeta.tracks[*it].codec == "AAC"){
PMT.setStreamType(0x0F,id);
}else if (myMeta.tracks[*it].codec == "MP3"){
PMT.setStreamType(0x03,id);
}
PMT.setElementaryPID(0x100 + (*it) - 1, id);
PMT.setESInfoLength(0,id);
id++;
}
PMT.calcCRC();
INFO_MSG("stringsize: %d %s", PMT.getStrBuf().size(), PMT.toPrettyString(0).c_str());
return PMT.getStrBuf();
}
void OutTS::sendHeader(){
/// \todo Update this to actually generate these from the selected tracks.
/// \todo ts_packet.h contains all neccesary info for this
/// \todo if --tracks is set, clear selected tracks and fill with --tracks tracks.
myConn.SendNow(TS::PAT, 188);
myConn.SendNow(TS::PMT, 188);
/// \todo Find a nice way to not use strings in this case
std::string pmt = createPMT();
myConn.SendNow(pmt.c_str(), 188);
//myConn.SendNow(TS::PMT, 188);
sentHeader = true;
}

View file

@ -1,6 +1,7 @@
#include "output.h"
#include <mist/mp4_generic.h>
#include <mist/ts_packet.h>
#include <string>
namespace Mist {
class OutTS : public Output {
@ -17,6 +18,7 @@ namespace Mist {
char VideoCounter;
char AudioCounter;
MP4::AVCC avccbox;
std::string createPMT();
};
}