0
我想我在這裏有一個隧道視覺,所以我需要你的幫助。C++ - MPEG TS - 解析頭 - PID搞砸了 - 大端32位掩碼
我想解析一個MPEG Transport-stream file,我被困在Header上,在wiki上你會看到爲了從4字節頭中提取數據而提供了一些32位的BE MASK。我的代碼考慮了endianess(我認爲),並在檢測到您運行的是小端時反轉了字節。然後,我投了char *到int和敷面膜,所有的值看起來不錯,但PID被搞砸了,我不知道爲什麼......
頭定義
namespace ts {
#define SYNC_BYTE_MASK 0xff000000
#define TEI_MASK 0x800000
#define PAYLOAD_START_MASK 0x400000
#define PRIORITY_MASK 0x200000
#define PID_MASK 0x1fff00
#define SCRAMBLING_CTL_MASK 0xc0
#define ADAPTATION_FIELD_MASK 0x20
#define HAS_PAYLOAD_MASK 0x10
#define COUNTER_MASK 0xf
#define HEADER_BYTES 4
#define HEADER_BITS 8 * HEADER_BYTES
class Header {
public:
std::bitset<HEADER_BITS> *full;
unsigned char _syncByte;
bool _tei;
bool _payloadStart;
bool _priority;
int16_t _pid;
std::bitset<2> *_scramblingCtl;
bool _adaptationField;
bool _hasPayload;
int _counter;
Header(const char *, size_t);
~Header();
const std::string toString();
bool isValid();
};
}
頁眉值分配
ts::Header::Header(const char *header, size_t n) {
uint32_t bytes = reverseLE(header, n);
// just for display
char t[4];
memcpy(t, header, 4);
std::cout << "Original: " << std::bitset<32>(*((uint32_t *)t)) << std::endl;
this->full = new std::bitset<HEADER_BITS>(bytes);
uint32_t tmp = bytes & SYNC_BYTE_MASK;
this->_syncByte = ((char *)&tmp)[n - 1];
this->_tei = bytes & TEI_MASK;
this->_payloadStart = bytes & PAYLOAD_START_MASK;
this->_priority = bytes & PRIORITY_MASK;
this->_pid = bytes & PID_MASK; // THIS ONE IS MESSED UP !!
this->_scramblingCtl = new std::bitset<2>(bytes & SCRAMBLING_CTL_MASK);
this->_adaptationField = bytes & ADAPTATION_FIELD_MASK;
this->_hasPayload = bytes & HAS_PAYLOAD_MASK;
this->_counter = bytes & COUNTER_MASK;
}
個
功能逆轉
#include "utils.h"
int is_big_endian(void)
{
union {
uint32_t i;
char c[4];
} e = { 0x01000000 };
return e.c[0];
}
void swap(char *s, int a, int b) {
char tmp;
tmp = s[a];
s[a] = s[b];
s[b] = tmp;
}
// Converts string to int taking endianess into account
uint32_t reverseLE(const char *bits, size_t n) {
uint32_t ret = 0;
char *cp = (char *)malloc(n * sizeof(char));
memcpy(cp, bits, n);
if (! is_big_endian()) {
for (int i = 0; i < n/2; i++)
swap(cp, i, n - 1 - i);
}
ret = *((uint32_t *)cp);
free(cp);
return ret;
}
下面是應該有33
Original: 00010010001000010000000001000111
Binary: 01000111000000000010000100010010
Sync byte: G
TEI: 0
Payload start: 0
Priority: 0
PID: 8448 0010000100000000
Scrambling Ctl: 00
Adaptation field: 0
Has Payload: 1
Counter: 2
不知怎的,它被再次逆轉,我不知道爲什麼一個PID的頭示例...
您不需要反轉字節,因爲您沒有讀取整數,但是您正在讀取4個字節。他們將始終以正確的順序。但是使用bitset輸出它們可能是個問題。 – wimh
因爲我需要在一個int上應用MASK(BE),並且我的機器是LE,所以如果我在轉換之前沒有反轉,它會搞砸了,對吧?當我離開它時,bools設置不正確,我也沒有看到PID :( – Maresh
我看到,你確實使用了整數,但是如果你使用'0x1fff00',你應該將結果移位8位(在所以你的例子有PID 33. – wimh