Beispiel #1
0
bool Header::Write(IOBuffer &buffer) {
	if (ci < 64) {
		buffer.ReadFromByte((ht << 6) | ((uint8_t) ci));
	} else if (ci < 319) {
		buffer.ReadFromByte(ht << 6);
		buffer.ReadFromByte((uint8_t) (ci - 64));
	} else if (ci < 65599) {
		uint16_t temp = EHTONS((uint16_t) (ci - 64));
		buffer.ReadFromByte((ht << 6) | 0x01);
		buffer.ReadFromBuffer((uint8_t *) & temp, 2);
	} else {
		FATAL("Invalid channel index");
		return false;
	}

	switch (ht) {
		case HT_FULL:
		{
			if (hf.s.ts < 0x00ffffff) {
				hf.s.ts = EHTONL(hf.s.ts); //----MARKED-LONG---
				hf.s.ml = EHTONL(hf.s.ml << 8); //----MARKED-LONG---
				buffer.ReadFromBuffer(&hf.datac[1], 11);
				hf.s.ts = ENTOHL(hf.s.ts); //----MARKED-LONG---
				hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---
				return true;
			} else {
				uint32_t temp = EHTONL(hf.s.ts); //----MARKED-LONG---
				hf.s.ts = EHTONL(0x00ffffff); //----MARKED-LONG---
				hf.s.ml = EHTONL(hf.s.ml << 8); //----MARKED-LONG---
				buffer.ReadFromBuffer(&hf.datac[1], 11);
				hf.s.ts = ENTOHL(temp); //----MARKED-LONG---
				hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---
				buffer.ReadFromBuffer((uint8_t *) & temp, 4);
				return true;
			}
		}
Beispiel #2
0
string U32TOS(uint32_t type) {
	type = ENTOHL(type);
	return string((char *) & (type), 4);
}
void CommonTestsSuite::test_Endianess() {
	uint16_t ui16 = 0x0102;
	uint32_t ui32 = 0x01020304;
	uint64_t ui64 = 0x0102030405060708LL;
	double d = 123.456;

	//host to network
	uint8_t *pBuffer = NULL;
	ui16 = EHTONS(ui16);
	pBuffer = (uint8_t *) & ui16;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);

	pBuffer = NULL;
	ui32 = EHTONL(ui32);
	pBuffer = (uint8_t *) & ui32;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);
	TS_ASSERT(pBuffer[2] == 0x03);
	TS_ASSERT(pBuffer[3] == 0x04);

	pBuffer = NULL;
	ui32 = 0x01020304;
	ui32 = EHTONA(ui32);
	pBuffer = (uint8_t *) & ui32;
	TS_ASSERT(pBuffer[0] == 0x02);
	TS_ASSERT(pBuffer[1] == 0x03);
	TS_ASSERT(pBuffer[2] == 0x04);
	TS_ASSERT(pBuffer[3] == 0x01);

	pBuffer = NULL;
	ui64 = EHTONLL(ui64);
	pBuffer = (uint8_t *) & ui64;
	TS_ASSERT(pBuffer[0] == 0x01);
	TS_ASSERT(pBuffer[1] == 0x02);
	TS_ASSERT(pBuffer[2] == 0x03);
	TS_ASSERT(pBuffer[3] == 0x04);
	TS_ASSERT(pBuffer[4] == 0x05);
	TS_ASSERT(pBuffer[5] == 0x06);
	TS_ASSERT(pBuffer[6] == 0x07);
	TS_ASSERT(pBuffer[7] == 0x08);

	pBuffer = NULL;
	EHTOND(d, ui64);
	pBuffer = (uint8_t *) & ui64;
	TS_ASSERT(pBuffer[0] == 0x40);
	TS_ASSERT(pBuffer[1] == 0x5e);
	TS_ASSERT(pBuffer[2] == 0xdd);
	TS_ASSERT(pBuffer[3] == 0x2f);
	TS_ASSERT(pBuffer[4] == 0x1a);
	TS_ASSERT(pBuffer[5] == 0x9f);
	TS_ASSERT(pBuffer[6] == 0xbe);
	TS_ASSERT(pBuffer[7] == 0x77);

	//network to host pointer
	char buffer[] = {
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f,
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f
	};

	ui16 = ENTOHSP(buffer);
	TS_ASSERT(ui16 == 0x0001);
	ui16 = ENTOHSP(buffer + 1);
	TS_ASSERT(ui16 == 0x0102);
	ui16 = ENTOHSP(buffer + 2);
	TS_ASSERT(ui16 == 0x0203);
	ui16 = ENTOHSP(buffer + 3);
	TS_ASSERT(ui16 == 0x0304);
	ui16 = ENTOHSP(buffer + 4);
	TS_ASSERT(ui16 == 0x0405);
	ui16 = ENTOHSP(buffer + 5);
	TS_ASSERT(ui16 == 0x0506);
	ui16 = ENTOHSP(buffer + 6);
	TS_ASSERT(ui16 == 0x0607);
	ui16 = ENTOHSP(buffer + 7);
	TS_ASSERT(ui16 == 0x0708);
	ui16 = ENTOHSP(buffer + 8);
	TS_ASSERT(ui16 == 0x0809);
	ui16 = ENTOHSP(buffer + 9);
	TS_ASSERT(ui16 == 0x090a);
	ui16 = ENTOHSP(buffer + 10);
	TS_ASSERT(ui16 == 0x0a0b);
	ui16 = ENTOHSP(buffer + 11);
	TS_ASSERT(ui16 == 0x0b0c);
	ui16 = ENTOHSP(buffer + 12);
	TS_ASSERT(ui16 == 0x0c0d);
	ui16 = ENTOHSP(buffer + 13);
	TS_ASSERT(ui16 == 0x0d0e);
	ui16 = ENTOHSP(buffer + 14);
	TS_ASSERT(ui16 == 0x0e0f);

	ui32 = ENTOHLP(buffer);
	TS_ASSERT(ui32 == 0x00010203);
	ui32 = ENTOHLP(buffer + 1);
	TS_ASSERT(ui32 == 0x01020304);
	ui32 = ENTOHLP(buffer + 2);
	TS_ASSERT(ui32 == 0x02030405);
	ui32 = ENTOHLP(buffer + 3);
	TS_ASSERT(ui32 == 0x03040506);
	ui32 = ENTOHLP(buffer + 4);
	TS_ASSERT(ui32 == 0x04050607);
	ui32 = ENTOHLP(buffer + 5);
	TS_ASSERT(ui32 == 0x05060708);
	ui32 = ENTOHLP(buffer + 6);
	TS_ASSERT(ui32 == 0x06070809);
	ui32 = ENTOHLP(buffer + 7);
	TS_ASSERT(ui32 == 0x0708090a);
	ui32 = ENTOHLP(buffer + 8);
	TS_ASSERT(ui32 == 0x08090a0b);
	ui32 = ENTOHLP(buffer + 9);
	TS_ASSERT(ui32 == 0x090a0b0c);
	ui32 = ENTOHLP(buffer + 10);
	TS_ASSERT(ui32 == 0x0a0b0c0d);
	ui32 = ENTOHLP(buffer + 11);
	TS_ASSERT(ui32 == 0x0b0c0d0e);
	ui32 = ENTOHLP(buffer + 12);
	TS_ASSERT(ui32 == 0x0c0d0e0f);

	ui32 = ENTOHAP(buffer);
	TS_ASSERT(ui32 == 0x03000102);
	ui32 = ENTOHAP(buffer + 1);
	TS_ASSERT(ui32 == 0x04010203);
	ui32 = ENTOHAP(buffer + 2);
	TS_ASSERT(ui32 == 0x05020304);
	ui32 = ENTOHAP(buffer + 3);
	TS_ASSERT(ui32 == 0x06030405);
	ui32 = ENTOHAP(buffer + 4);
	TS_ASSERT(ui32 == 0x07040506);
	ui32 = ENTOHAP(buffer + 5);
	TS_ASSERT(ui32 == 0x08050607);
	ui32 = ENTOHAP(buffer + 6);
	TS_ASSERT(ui32 == 0x09060708);
	ui32 = ENTOHAP(buffer + 7);
	TS_ASSERT(ui32 == 0x0a070809);
	ui32 = ENTOHAP(buffer + 8);
	TS_ASSERT(ui32 == 0x0b08090a);
	ui32 = ENTOHAP(buffer + 9);
	TS_ASSERT(ui32 == 0x0c090a0b);
	ui32 = ENTOHAP(buffer + 10);
	TS_ASSERT(ui32 == 0x0d0a0b0c);
	ui32 = ENTOHAP(buffer + 11);
	TS_ASSERT(ui32 == 0x0e0b0c0d);
	ui32 = ENTOHAP(buffer + 12);
	TS_ASSERT(ui32 == 0x0f0c0d0e);

	ui64 = ENTOHLLP(buffer);
	TS_ASSERT(ui64 == 0x0001020304050607LL);
	ui64 = ENTOHLLP(buffer + 1);
	TS_ASSERT(ui64 == 0x0102030405060708LL);
	ui64 = ENTOHLLP(buffer + 2);
	TS_ASSERT(ui64 == 0x0203040506070809LL);
	ui64 = ENTOHLLP(buffer + 3);
	TS_ASSERT(ui64 == 0x030405060708090aLL);
	ui64 = ENTOHLLP(buffer + 4);
	TS_ASSERT(ui64 == 0x0405060708090a0bLL);
	ui64 = ENTOHLLP(buffer + 5);
	TS_ASSERT(ui64 == 0x05060708090a0b0cLL);
	ui64 = ENTOHLLP(buffer + 6);
	TS_ASSERT(ui64 == 0x060708090a0b0c0dLL);
	ui64 = ENTOHLLP(buffer + 7);
	TS_ASSERT(ui64 == 0x0708090a0b0c0d0eLL);
	ui64 = ENTOHLLP(buffer + 8);
	TS_ASSERT(ui64 == 0x08090a0b0c0d0e0fLL);

	char *pTempBuffer = new char[64 + 8];
	unsigned char rawDouble[] = {0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77};
	double tempDoubleVal = 0;
	for (int i = 0; i <= 64; i++) {
		memset(pTempBuffer, 0, i);
		memcpy(pTempBuffer + i, rawDouble, 8);
		memset(pTempBuffer + i + 8, 0, 64 + 8 - i - 8);
		ENTOHDP((pTempBuffer + i), tempDoubleVal);
		TS_ASSERT(d == tempDoubleVal);
	}
	delete[] pTempBuffer;

	//network to host
#ifdef LITTLE_ENDIAN_BYTE_ALIGNED
	TS_ASSERT(ENTOHA(0x01040302) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0807060504030201LL) == 0x0102030405060708LL);
	ENTOHD(0x77BE9F1A2FDD5E40LL, tempDoubleVal);
	TS_ASSERT(d == tempDoubleVal);
#endif /* LITTLE_ENDIAN_BYTE_ALIGNED */

#ifdef LITTLE_ENDIAN_SHORT_ALIGNED
	TS_ASSERT(ENTOHA(0x01040302) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0807060504030201LL) == 0x0102030405060708LL);
	ENTOHD(0x77BE9F1A2FDD5E40LL, tempDoubleVal);
	TS_ASSERT(d == tempDoubleVal);
#endif /* LITTLE_ENDIAN_SHORT_ALIGNED */

#ifdef BIG_ENDIAN_BYTE_ALIGNED
	TS_ASSERT(ENTOHA(0x02030401) == 0x01020304);
	TS_ASSERT(ENTOHLL(0x0102030405060708LL) == 0x0102030405060708LL);
#error ENTOHD not tested
#endif /* BIG_ENDIAN_BYTE_ALIGNED */

#ifdef BIG_ENDIAN_SHORT_ALIGNED
#error BIG_ENDIAN_SHORT_ALIGNED set of tests not yet implemented!!! Please take care of this first!!!
#endif /* BIG_ENDIAN_SHORT_ALIGNED */

	//double mirror
	TS_ASSERT(ENTOHS(EHTONS(0x0102)) == 0x0102);
	TS_ASSERT(EHTONS(ENTOHS(0x0102)) == 0x0102);

	TS_ASSERT(ENTOHL(EHTONL(0x01020304)) == 0x01020304);
	TS_ASSERT(EHTONL(ENTOHL(0x01020304)) == 0x01020304);

	TS_ASSERT(ENTOHLL(EHTONLL(0x0102030405060708LL)) == 0x0102030405060708LL);
	TS_ASSERT(EHTONLL(ENTOHLL(0x0102030405060708LL)) == 0x0102030405060708LL);

	//EHTOND/ENTOHD are different. Requires 2 parameters. So, no double mirror

	TS_ASSERT(ENTOHA(EHTONA(0x01020304)) == 0x01020304);
	TS_ASSERT(EHTONA(ENTOHA(0x01020304)) == 0x01020304);

	// Buffer Put routines
	for (int i = 0; i < 16; i++) {
		EHTONSP(buffer + i, 0x0102);
		TS_ASSERT(ENTOHSP(buffer + i) == 0x0102);

		EHTONLP(buffer + i, 0x01020304);
		TS_ASSERT(ENTOHLP(buffer + i) == 0x01020304);

		EHTONLLP(buffer + i, 0x0102030405060708LL);
		TS_ASSERT(ENTOHLLP(buffer + i) == 0x0102030405060708LL);

		EHTONDP(d, (buffer + i));
		ENTOHDP(buffer + i, tempDoubleVal);
		TS_ASSERT(d == tempDoubleVal);
	}
}
Beispiel #4
0
bool Header::Read(uint32_t channelId, uint8_t type, IOBuffer &buffer,
		uint32_t availableBytes) {
	ht = type;
	ci = channelId;

	switch (ht) {
		case HT_FULL:
		{
			isAbsolute = true;
			if (availableBytes < 11) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 11);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---
			hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 15) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 11);
				readCompleted = true;
				return buffer.Ignore(15);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(11);
			}
		}
		case HT_SAME_STREAM:
		{
			isAbsolute = false;
			if (availableBytes < 7) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 7);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---
			hf.s.ml = ENTOHL(hf.s.ml) >> 8; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 11) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 7);
				readCompleted = true;
				return buffer.Ignore(11);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(7);
			}
		}
		case HT_SAME_LENGTH_AND_STREAM:
		{
			isAbsolute = false;
			if (availableBytes < 3) {
				readCompleted = false;
				return true;
			}
			memcpy(hf.datac + 1, GETIBPOINTER(buffer), 3);
			hf.s.ts = ENTOHL(hf.s.ts)&0x00ffffff; //----MARKED-LONG---

			if (hf.s.ts == 0x00ffffff) {
				skip4bytes = true;
				if (availableBytes < 7) {
					readCompleted = false;
					return true;
				}
				hf.s.ts = ENTOHLP(GETIBPOINTER(buffer) + 3);
				readCompleted = true;
				return buffer.Ignore(7);
			} else {
				skip4bytes = false;
				readCompleted = true;
				return buffer.Ignore(3);
			}
		}
		case HT_CONTINUATION:
		{
			isAbsolute = false;
			if (skip4bytes) {
				if (availableBytes < 4) {
					readCompleted = false;
					return true;
				}
				readCompleted = true;
				return buffer.Ignore(4);
			} else {
				readCompleted = true;
				return true;
			}
		}
		default:
		{
			FATAL("Invalid header type: %hhu", ht);
			return false;
		}
	}
}
Beispiel #5
0
int MP4Parser::read_frame(File &file, Track *trak,
                          SampleEntry *sentry, Frame *f)
{
  if (!sentry || !f)
    return -1;

  int64_t decode_ts = sentry->decode_ts;
  uint32_t sample_idx = sentry->sample_idx;
  off_t sample_offset = sentry->sample_offset;
  uint32_t sample_sz = sentry->sample_sz;

  // Seek to where it is and read
  if (!file.seek_to(sample_offset)) {
    LOGE("Seek to sample_offset(%ld) failed", sample_offset);
    return -1;
  }

  // Read the frame
  uint8_t *dat = (uint8_t *) malloc(sample_sz+7); // 7 is for adts-header length
  if (!dat) {
    LOGE("malloc for sample failed: %s", ERRNOMSG);
    return -1;
  }
  if (!file.read_buffer(trak->video_track ? dat : dat+7, sample_sz)) {
    LOGE("Read frame failed, sample_offset: %ld, sample_idx: %u, sample_sz: 0x%08x",
         sample_offset, sample_idx, sample_sz);
    SAFE_FREE(dat);
    return -1;
  }

  if (trak->video_track) { // Video track
    bool is_keyframe = false; // Whether this is a keyframe
    bool got_sps = false;     // Keyframe whether has sps & pps

    // Convert 4bytes nalu-length to 00 00 00 01
    uint32_t nalu_offset = 0;
    while (nalu_offset < sample_sz) {
      uint32_t nalu_size = ENTOHL(*(uint32_t *)(dat+nalu_offset));

      put_be32(dat+nalu_offset, 0x00000001);

      uint8_t nalu_typ = *(dat+nalu_offset+4)&0x1F;
      if (nalu_typ == 0x07) {
        // Keyframe with sps (pps is also followed)
        got_sps = true;
        is_keyframe = true;
      } else if (!got_sps &&
          (nalu_typ == 0x08 ||
           nalu_typ == 0x06 ||
           nalu_typ == 0x05)) {
        // Keyframe with sps and pps in box "avcC"
        is_keyframe = true;
      }

      // Handle next nalu in this frame
      nalu_offset += nalu_size + 4;
    }

    if (is_keyframe && !got_sps) {
      // Recover sps&pps from box "avcC" to make it a complete I-Frame
      AVCDecorderConfigurationRecord &avc_dcr = trak->avcC->avc_dcr;
      uint8_t *complete_frame = (uint8_t *) malloc (
          4+avc_dcr.sps_length+
          4+avc_dcr.pps_length+
          sample_sz);
      if (!complete_frame) {
        LOGE("malloc for complete_frame failed: %s", ERRNOMSG);
        SAFE_FREE(dat);
        return -1;
      }
      // Copy startcode and sps
      put_be32(complete_frame, 0x00000001);
      memcpy(complete_frame+4,
             avc_dcr.sps, avc_dcr.sps_length);
      // Copy startcode and pps
      put_be32(complete_frame+4+avc_dcr.sps_length, 0x00000001);
      memcpy(complete_frame+4+avc_dcr.sps_length+4,
             avc_dcr.pps, avc_dcr.pps_length);
      // Copy the rest of video frame
      memcpy(complete_frame+4+avc_dcr.sps_length+4+avc_dcr.pps_length,
             dat, sample_sz);
      SAFE_FREE(dat);
      // Update the frame statistics
      sample_sz += 4+avc_dcr.sps_length+4+avc_dcr.pps_length;
      dat = complete_frame;
    }
  } else { // Audio track
    // Add adts header to the begining of frame
    generate_adts_header(trak->esds->asc, sample_sz, dat);
    // Update the frame statistics
    sample_sz += 7;
  }

  return f->make_frame(decode_ts, dat, sample_sz, true, sentry->composition_time);
}