Selaa lähdekoodia

libobs: Add function to extract AVC header/sei

Allows extraction of headers/sei from a frame so that an encoder can
separate those headers and provide them for later use.
jp9000 9 vuotta sitten
vanhempi
sitoutus
1a38d779c9
2 muutettua tiedostoa jossa 59 lisäystä ja 0 poistoa
  1. 55 0
      libobs/obs-avc.c
  2. 4 0
      libobs/obs-avc.h

+ 55 - 0
libobs/obs-avc.c

@@ -221,3 +221,58 @@ size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data, size_t size)
 	*header = output.bytes.array;
 	return output.bytes.num;
 }
+
+void obs_extract_avc_headers(const uint8_t *packet, size_t size,
+		uint8_t **new_packet_data, size_t *new_packet_size,
+		uint8_t **header_data, size_t *header_size,
+		uint8_t **sei_data, size_t *sei_size)
+{
+	DARRAY(uint8_t) new_packet;
+	DARRAY(uint8_t) header;
+	DARRAY(uint8_t) sei;
+	const uint8_t *nal_start, *nal_end, *nal_codestart;
+	const uint8_t *end = packet + size;
+	int type;
+
+	da_init(new_packet);
+	da_init(header);
+	da_init(sei);
+
+	nal_start = obs_avc_find_startcode(packet, end);
+	nal_end = NULL;
+	while (nal_end != end) {
+		nal_codestart = nal_start;
+
+		while (nal_start < end && !*(nal_start++));
+
+		if (nal_start == end)
+			break;
+
+		type = nal_start[0] & 0x1F;
+
+		nal_end = obs_avc_find_startcode(nal_start, end);
+		if (!nal_end)
+			nal_end = end;
+
+		if (type == OBS_NAL_SPS || type == OBS_NAL_PPS) {
+			da_push_back_array(header, nal_codestart,
+					nal_end - nal_codestart);
+		} else if (type == OBS_NAL_SEI) {
+			da_push_back_array(sei, nal_codestart,
+					nal_end - nal_codestart);
+
+		} else {
+			da_push_back_array(new_packet, nal_codestart,
+					nal_end - nal_codestart);
+		}
+
+		nal_start = nal_end;
+	}
+
+	*new_packet_data = new_packet.array;
+	*new_packet_size = new_packet.num;
+	*header_data = header.array;
+	*header_size = header.num;
+	*sei_data = sei.array;
+	*sei_size = sei.num;
+}

+ 4 - 0
libobs/obs-avc.h

@@ -55,6 +55,10 @@ EXPORT void obs_parse_avc_packet(struct encoder_packet *avc_packet,
 		const struct encoder_packet *src);
 EXPORT size_t obs_parse_avc_header(uint8_t **header, const uint8_t *data,
 		size_t size);
+EXPORT void obs_extract_avc_headers(const uint8_t *packet, size_t size,
+		uint8_t **new_packet_data, size_t *new_packet_size,
+		uint8_t **header_data, size_t *header_size,
+		uint8_t **sei_data, size_t *sei_size);
 
 #ifdef __cplusplus
 }