I am streaming a video in python via WebSocket, which is a raw bytes stream and appears like this:
b'\x00\x00\x00\x01A\x9a \x02\x04\xe1{=z\xf8FMS\xe6\\\x9eMubH\xa7R.1\xd7]F\xea3}\xa9b\x9f\x14n\x12| ....'
Now, I am passing these bytes to a C function (via ctypes) where I am trying to convert this to a uint8_t [] array (This is needed in order to decode it using a FFmpeg library). Here's my code so far:
This is how I am passing bytes to C:
import ctypes
dll = ctypes.CDLL("decode_video.so")
data = bytearray(b'\x00\x00\x00\x01A\x9a \x02\x04\xe1-{=z\xf8FM....')
b_array = ctypes.c_char * len(data)
dll.conversion_test(b_array.from_buffer(data), len(data))
decode_video.c
void conversion_test(unsigned char* buf, int bufSize) {
char temp[3];
uint8_t vals[bufSize];
// Iterate over the values
for (int i = 0; i < bufSize; i++) {
// Copy two characters into the temporary string
temp[0] = buf[i * 2];
temp[1] = buf[i * 2 + 1];
temp[2] = 0;
vals[i] = strtol(temp, NULL, 16);
}
for(int i=0; i<bufSize; i++){
printf("%02x ", vals[i] & 0xff);
}
}
Aside from this, I am simultaneously dumping the stream to a file. In C, I have another function that reads from this file and stores in a uint8_t buffer.
Streaming code in python:
f = open("video.h264", "wb")
def on_message(ws, message):
# The first 14 characters have irrelevant info to decode the video
f.write(message[14:])
ws = websocket.WebSocketApp("wss://somewebsite.com/archives",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close,
header=[protocol_str]
)
ws.binaryType = 'arraybuffer'
ws.run_forever(dispatcher=rel)
Reading from the raw file in C:
#include "libavcodec/avcodec.h"
#define INBUF_SIZE 4096
uint8_t *data;
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
f = fopen(input_name, "rb");
data_size = fread(inbuf, 1, INBUF_SIZE, f);
// Printing bytes in hex to debug
for(size_t i=0; i<data_size; i++){
printf("%02x ", inbuf[i] & 0xff);
}
However the contents of this inbuf
and output of the vals
buffer are not the same. Basically, I am unsure of my method of passing bytes to C and its corresponding coversion to uint8_t.
Update:
I tried printing the hex values of vals
and here's what it looks like:
00 00 0a 00 00 00 00 00 00 00 00 00 00 00 01 00 00 ...
While the output of inbuf
looks like this:
00 00 00 01 67 42 00 1e e2 90 14 07 b6 02 dc ...
As suggested by @n. m. and @dreamlax, a simple identity mapping works between unsigned char and uint8_t. Now vals and inbuf output the same values!
void conversion_test(unsigned char* buf, int bufSize) {
uint8_t vals[bufSize];
for(int i = 0; i < bufSize; i++)
vals[i] = (uint8_t)buf[i];
}
(OR) A simple type-casting
uint8_t *vals = (uint8_t *)ubuf;