java获取摄像头h.264视频流_rtmp视频流提取h264裸流

流媒体服务器在判断出消息类型为video之后,进行h264参数集和nalu的提取,并加入分隔符,代码如下

文中用读取文件的方式代替rtmp msg里面的payload

rtmp视频消息示例:

d7f891414e3f

image.png

。。。。

d7f891414e3f

image.png

#include

#include

FILE *f264 = NULL;

uint16_t ReadU16BE(uint8_t data[2]) {

uint16_t v = 0;

uint16_t v1 = uint16_t(data[0]);

v1 <<= 16;

uint16_t v2 = uint16_t(data[1]);

v |= v1;

v |= v2;

return v;

}

uint32_t ReadU32BE(uint8_t data[4]) {

uint32_t v = 0;

uint32_t v1 = uint32_t(data[0]);

v1 <<= 24;

uint32_t v2 = uint32_t(data[1]);

v2 <<= 16;

uint32_t v3 = uint32_t(data[2]);

v3 <<= 8;

uint32_t v4 = uint32_t(data[3]);

v |= v1;

v |= v2;

v |= v3;

v |= v4;

return v;

}

void write_h264nalu_to_disk(char *nalu, int nalu_len) {

char separator[4] = {0x00, 0x00, 0x00, 0x01};

fwrite(separator, 1, 4, f264);

fwrite(nalu, 1, nalu_len, f264);

}

void parse_one_frame(char *payload, int payload_size) {

char frame_type = payload[0];

frame_type = (frame_type >> 4) & 0x0F;

char avc_packet_type = payload[1];

if (1 == frame_type && 0 == avc_packet_type)// spspps. 17 00

{

//sps

int offset = 0;

offset += 11;

int sps_len = payload[offset] * 16 + payload[offset + 1];

offset += 2;

write_h264nalu_to_disk(&payload[offset], sps_len);

offset += sps_len;

//pps

offset += 1; //pps num.

char nalu_len_data[2] = {payload[offset], payload[offset + 1]};

int pps_len = ReadU16BE((uint8_t *) nalu_len_data);

offset += 2;

offset + pps_len;

write_h264nalu_to_disk(&payload[offset], pps_len);

} else if (1 == avc_packet_type) // nalu

{

int offset = 0;

offset += 5;

while (offset < payload_size) {

char nalu_len_data[4] = {payload[offset], payload[offset + 1], payload[offset + 2], payload[offset + 3]};

int nalu_len = ReadU32BE((uint8_t *) nalu_len_data);

offset += 4;

write_h264nalu_to_disk(&payload[offset], nalu_len);

offset += nalu_len;

}

}

}

int main() {

std::string path = "/home/yangkai/CLionProjects/jvsrs/trunk/cmake-build-debug/origin/";

enum {

READ_EVERY_TIME = 128

};

char *payload = new char[1 * 1024 * 1024];

int payload_size = 0;

f264 = fopen("end.264", "wb+");

for (int i = 0; i < 1956; ++i) {

std::stringstream ss;

ss << path << "origin-" << i << ".h264";

FILE *f = fopen(ss.str().c_str(), "rb");

while (1) {

int readsize = fread(payload + payload_size, 1, READ_EVERY_TIME, f);

payload_size += readsize;

if (readsize != READ_EVERY_TIME) {

break;

}

}

fclose(f);

parse_one_frame(payload, payload_size);

payload_size = 0;

}

delete[] payload;

fclose(f264);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值