#include "tspacket.h" //#include "debug.h" //#include "dprintf.h" // Cria pacote nulo de 188 bytes void create_ts_null_packet(unsigned char *buffer){ unsigned char nullPacket [188]= { 0x47, 0x1F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; memcpy(buffer, nullPacket, 188); return; } /** * Retorna error se value <= 0 * * @param value -> valor a ser avaliado **/ char assert(int value) { if (value <= 0) { printf("Error no assert %d\n", value); return 0; } else return 1; } /** * retorna zero se n???o h??? adaptation field, ou diferente de zero se h??? * * @param pacote -> pacote TS de 188 bytes **/ char hasAdaptationField(unsigned char * pacote) { return getAdaptationFieldControl(pacote) == AFC_ONLY_ADAPT_FIELD || getAdaptationFieldControl(pacote) == AFC_BOTH_PAYLOAD_AND_ADAPT_FIELD; } /** * retorna o adaptation field len * * @param pacote -> pacote TS de 188 bytes **/ unsigned int getAdaptationFieldLength(unsigned char * pacote) { if ( hasAdaptationField(pacote) ) { unsigned aFieldLength = pacote[4]; // 5 byte switch (getAdaptationFieldControl(pacote)) { case AFC_ONLY_ADAPT_FIELD: //assert(aFieldLength == 183); //break; if (aFieldLength == 183) break; else return 0; case AFC_BOTH_PAYLOAD_AND_ADAPT_FIELD: //assert(0 <= aFieldLength && aFieldLength <= 182); //break; if(0 <= aFieldLength && aFieldLength <= 182) break; else return 0; default: break; } return aFieldLength; } else return 0; } void setAdaptationFieldLength(unsigned char * pacote, int length) { if ( hasAdaptationField(pacote) ) { pacote[4] = length; } } /** * Retorna o tamanho do payload * * @param pacote -> pacote TS de 188 bytes **/ unsigned int getPayloadLength(unsigned char * pacote) { int aFieldControl = getAdaptationFieldControl(pacote); if (aFieldControl & 0x1) { /* aFieldControl is either 0x1 or 0x3: payload is present */ unsigned aFieldLength = 0; if (aFieldControl == 0x3) /* adaption field is present */ aFieldLength = getAdaptationFieldLength(pacote) + 1; /* the '1' is to include the aFieldLength itself */ if (aFieldLength <= 183) return MAX_PAYLOAD_SIZE - aFieldLength; } return 0; /* nao h??? payload */ } // proveitoso, recompesador, valer a pena, prof???cuo /** * Retorna um ponteiro para o in???cio do payload no pacote. * * @param pacote -> pacote TS de 188 bytes * @param length -> vari???vel que receber??? o tamanho do payload */ unsigned char * getPayload(unsigned char * pacote, unsigned int * length) { (*length) = getPayloadLength(pacote); if ( (*length) == 0 ) return NULL; return &pacote[PACKET_SIZE - (*length)]; } /// Gets... int getSyncByte(unsigned char * pacote) { return pacote[0]; } // retorna 1 ou zero char getTransportErrorIndicator(unsigned char * pacote) { return (pacote[1] & 0x80) >> 7; } /** * retorna 0x40 se existir o payload unit start indication, e zero se nao existir * @param pacote -> pacote TS de 188 bytes **/ unsigned char getPayloadUnitStartIndicator(unsigned char * pacote) { return (pacote[1] & 0x40) >> 6; } // retorna 1 ou zero char getTransportPriority(unsigned char * pacote) { return (pacote[1] & 0x20) >> 5; } /** * retorna o pid do pacote TS * @param pacote -> pacote TS de 188 bytes **/ int getPid(unsigned char * pacote) { return ((pacote[1] & 0x1F) << 8) | pacote[2]; } char getTransportScramblingControl(unsigned char * pacote) { unsigned sControl = (pacote[3] & 0xC0) >> 6; switch (sControl) { case 0x1: return SC_USER_DEFINED_1; case 0x2: return SC_USER_DEFINED_2; case 0x3: return SC_USER_DEFINED_3; } return SC_NOT_SCRAMBLED; } /** * retorna o adaptation field control * @param pacote -> pacote TS de 188 bytes **/ unsigned int getAdaptationFieldControl(unsigned char * pacote) { unsigned int aFieldControl = (pacote[3] & 0x30) >> 4; switch (aFieldControl) { case 0x1: return AFC_ONLY_PAYLOAD; case 0x2: return AFC_ONLY_ADAPT_FIELD; case 0x3: return AFC_BOTH_PAYLOAD_AND_ADAPT_FIELD; } return AFC_RESERVED; } unsigned getContinuityCounter(unsigned char * pacote) { return pacote[3] & 0x0F; } /// Sets... // Value deve ser setado para 71 decimal, ou 47 hexa void setSyncByte(unsigned char * pacote, int value) { pacote[0] = value; } // transportError deve ser 0 ou 1 void setTransportErrorIndicator(unsigned char * pacote, unsigned char transportError) { pacote[1] = (pacote[1] & 0x7F) | (transportError << 7); } // payloadUnitStart deve ser 0 ou 1 void setPayloadUnitStartIndicator(unsigned char * pacote, unsigned char payloadUnitStart) { pacote[1] = (pacote[1] & 0xBF) | (payloadUnitStart << 6); } // transportError deve ser 0 ou 1 void setTransportPriority(unsigned char * pacote, unsigned char transportPriority) { pacote[1] = (pacote[1] & 0xDF) | (transportPriority << 5); } // pid contem 13 bits void setPid(unsigned char * pacote, int pid) { pacote[1] = (pacote[1] & 0xE0) | ((pid & 0x1F00) >> 8); pacote[2] = pid & 0x00FF; } // scramblingControl contem 2 bits void setTransportScramblingControl(unsigned char * pacote, unsigned char scramblingControl) { pacote[3] = (pacote[3] & 0x3F) | ((scramblingControl << 6) & 0xC0); } // adaptationFieldControl contem 2 bits void setAdaptationFieldControl(unsigned char * pacote, unsigned char adaptationFieldControl) { pacote[3] = (pacote[3] & 0xCF) | ((adaptationFieldControl & 0x3) << 4); } //continuityConter deve ser sempre incrementado externamente a essa funcao, mas seele ultrapassar 15, // recebe zero void setContinuityCounter(unsigned char * pacote, unsigned char continuityCounter) { continuityCounter = continuityCounter % 16; pacote[3] = (pacote[3] & 0xF0) | (continuityCounter & 0x0F); } void setPayload(unsigned char * pacote, unsigned char *data, unsigned length) { unsigned available; unsigned char *payload = getPayload(pacote, &available); /* be sure that the available data is enough */ if (length <= available) { /* copy data */ memcpy(payload, data, length); /* fill the remaining data with stuffing bytes */ memset(payload + length, STUFFING_BYTE, available - length); } else printf("Error, tentando setar o payload (%d) maior que o espa???o disponivel(%d)\n", length, available); } char getDiscontinuityIndicator(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x80; /* 1000 0000 */ } else return 0; } char getRandomAccessIndicator(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x40; /* 0100 0000 */ } else return 0; } char getElementaryStreamPriorityIndicator(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x20; /* 0010 0000 */ } else return 0; } void setDiscontinuityIndicator(unsigned char * pacote, int value) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0x7F) | ((value<<7) & 0x80); /* 1000 0000 */ } } void setRandomAccessIndicator(unsigned char * pacote, int value) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xBF) | ((value<<6) & 0x40); /* 0100 0000 */ } } void setElementaryStreamPriorityIndicator(unsigned char * pacote, int value) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xDF) | ((value << 5)& 0x20); /* 0010 0000 */ } } char getOpcrFlag(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x08; /* 0000 1000 */ } else return NULL; } void setOpcrFlag(unsigned char * pacote, char flag) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xF7) | ((flag<<3) & 0x08); } } char getPcrFlag(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x10; /* 0001 0000 */ } else return 0; } void setPcrFlag(unsigned char * pacote, char flag) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xEF) | ((flag<<4) & 0x10); } } char getSplicingPointFlag(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x04; /* 0000 0100 */ } else return 0; } void setSplicingPointFlag(unsigned char * pacote, char flag) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xFB) | ((flag<<2) & 0x04); /* 0000 0100 */ } } char getTransportPrivateDataFlag(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x02; /* 0000 0010 */ } else return 0; } void setTransportPrivateDataFlag(unsigned char * pacote, char flag) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xFD) | ((flag<<1) & 0x02); /* 0000 0010 */ } } char getAdaptationFieldExtensionFlag(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { return pacote[5] & 0x01; /* 0000 0001 */ } else return 0; } void setAdaptationFieldExtensionFlag(unsigned char * pacote, char flag) { if (getAdaptationFieldLength(pacote)) { pacote[5] = (pacote[5] & 0xFE) | (flag & 0x01); /* 0000 0001 */ } } void setFlagsZero(unsigned char * pacote) { if (getAdaptationFieldLength(pacote)) { pacote[5] = pacote[5] & 0xE0; } } char hasPcr(unsigned char * pacote) { return hasAdaptationField(pacote) && (getAdaptationFieldLength(pacote) != 0) && getPcrFlag(pacote); } int64_t getPcrBase(unsigned char * pacote) { /* 33 */ // if (hasPcr(pacote)) // comentei para otimizar o codigo { return ( ( ((uint64_t) pacote[ 6])<< 25 ) | ( pacote[ 7] << 17 ) | ( pacote[ 8] << 9 ) | ( pacote[ 9] << 1 ) | ( pacote[10] >> 7 ) ); //+ (((uint64_t)1000000000)*7) + (((uint64_t)100000000)*4) +(((uint64_t)10000000)*6);//testes } // else // return 0; /* (( (((uint64_t) pacote[6]) << 25)) & (((uint64_t) 0x1FE00000)<<4 ) ) | (( (uint64_t) (pacote[ 7] << 17)) & ( 0x001FE0000) ) | (( (uint64_t) (pacote[ 8] << 9)) & ( 0x00001FE00) ) | (( (uint64_t) (pacote[ 9] << 1)) & ( 0x0000001FE) ) | (( (uint64_t) (pacote[10] >> 7)) & ( 0x000000001) ) ); */ } void setPcrBase(unsigned char * pacote, int64_t pcrBase) { /* 33 */ // if (hasPcr(pacote)) // comentei para ficar mais rapido { pacote[ 6] = pcrBase>>25; pacote[ 7] = pcrBase>>17; pacote[ 8] = pcrBase>>9; pacote[ 9] = pcrBase>>1; pacote[10] = ((pcrBase<<7) & 0x80) | (pacote[10] & 0x7F); } } int64_t getPcrExtension(unsigned char * pacote) { return ((pacote[10] & 0x1) << 8) | pacote[11]; } void setPcrExtension(unsigned char * pacote, int64_t pcrExtension) { pacote[10] = ((pcrExtension>>8) & 0x01) | (pacote[10] & 0xFE); pacote[11] = pcrExtension; } unsigned getSectionLength(unsigned char * section) { unsigned sectionLength = ((section[1] & 0x0F) << 8) | section[2]; /* ITU-T H.222.0 2.4.4.11 page 48 (private section length) */ if (sectionLength >= 4094) { printf("tamanho de pat section invalido (%d), maximo 4093\n", sectionLength); return 0; } return sectionLength; } unsigned getSectionDataLength(unsigned char * section) { // +3, pq tem 3 bytes antes do campo sectionLength return getSectionLength(section) + 3; } unsigned int generateGenericTsPackets(unsigned char * tsPacketInitial, int pid, unsigned char * section, unsigned int tableSize) { int sectionSize = tableSize; unsigned char * temp = (unsigned char *) malloc(184); unsigned char * tsPacket; int remainBytes = 0; int payloadSize = 0; unsigned int quantPacotes =1; int cc = 0; memset(temp, 0xFF, 184); tsPacket = tsPacketInitial; if (sectionSize > 183) payloadSize = 183; else payloadSize = sectionSize; temp[0] = 0; memcpy(&temp[1], section, payloadSize); remainBytes = sectionSize; setSyncByte (tsPacket, SYNC_BYTE); setTransportErrorIndicator (tsPacket, 0); setPayloadUnitStartIndicator (tsPacket, 1); // 1 == first packet setTransportPriority (tsPacket, 0); setPid (tsPacket, pid); setTransportScramblingControl(tsPacket, SC_NOT_SCRAMBLED); setAdaptationFieldControl (tsPacket, AFC_ONLY_PAYLOAD); setContinuityCounter (tsPacket, cc++); setPayload (tsPacket, temp, payloadSize+1); free(temp); /*printf("Pat: "); for (i = 0; i < 188; i++){ printf("%x ", tsPacket[i]); }*/ remainBytes -= payloadSize; while (remainBytes>0) { // printf("entrei no while, remainBytes == %d, payloadSize == %d \n", remainBytes,payloadSize); quantPacotes++; tsPacket = tsPacket + PACKET_SIZE; section = section + payloadSize; if (remainBytes > 184) payloadSize = 184; else payloadSize = remainBytes; setSyncByte (tsPacket, SYNC_BYTE); setTransportErrorIndicator (tsPacket, 0); setPayloadUnitStartIndicator (tsPacket, 0); // 0 == not the first packet setTransportPriority (tsPacket, 0); setPid (tsPacket, pid); setTransportScramblingControl(tsPacket, SC_NOT_SCRAMBLED); setAdaptationFieldControl (tsPacket, AFC_ONLY_PAYLOAD); setContinuityCounter (tsPacket, cc++); setPayload (tsPacket, section, payloadSize); remainBytes -= payloadSize; } return quantPacotes; } unsigned int generateTsPacket(unsigned char * tsPacketInitial, int pid, unsigned char * section) { int sectionSize = getSectionDataLength(section); unsigned char * temp = (unsigned char *) malloc(184); unsigned char * tsPacket; int remainBytes = 0; int payloadSize = 0; unsigned int quantPacotes =1; int cc = 0; memset(temp, 0xFF, 184); tsPacket = tsPacketInitial; if (sectionSize > 183) payloadSize = 183; else payloadSize = sectionSize; temp[0] = 0; memcpy(&temp[1], section, payloadSize); remainBytes = sectionSize; setSyncByte (tsPacket, SYNC_BYTE); setTransportErrorIndicator (tsPacket, 0); setPayloadUnitStartIndicator (tsPacket, 1); // 1 == first packet setTransportPriority (tsPacket, 0); setPid (tsPacket, pid); setTransportScramblingControl(tsPacket, SC_NOT_SCRAMBLED); setAdaptationFieldControl (tsPacket, AFC_ONLY_PAYLOAD); setContinuityCounter (tsPacket, cc++); setPayload (tsPacket, temp, payloadSize+1); free(temp); /*printf("Pat: "); for (i = 0; i < 188; i++){ printf("%x ", tsPacket[i]); }*/ remainBytes -= payloadSize; while (remainBytes>0) { // printf("entrei no while, remainBytes == %d, payloadSize == %d \n", remainBytes,payloadSize); quantPacotes++; tsPacket = tsPacket + PACKET_SIZE; section = section + payloadSize; if (remainBytes > 184) payloadSize = 184; else payloadSize = remainBytes; setSyncByte (tsPacket, SYNC_BYTE); setTransportErrorIndicator (tsPacket, 0); setPayloadUnitStartIndicator (tsPacket, 0); // 0 == not the first packet setTransportPriority (tsPacket, 0); setPid (tsPacket, pid); setTransportScramblingControl(tsPacket, SC_NOT_SCRAMBLED); setAdaptationFieldControl (tsPacket, AFC_ONLY_PAYLOAD); setContinuityCounter (tsPacket, cc++); setPayload (tsPacket, section, payloadSize); remainBytes -= payloadSize; } return quantPacotes; }