1
0
Эх сурвалжийг харах

obs-outputs: Set AV1 packet priority

derrod 1 жил өмнө
parent
commit
4e18bb6e50

+ 49 - 2
plugins/obs-outputs/rtmp-av1.c

@@ -33,11 +33,19 @@
 #define AV1_OBU_TILE_GROUP 4
 #define AV1_OBU_TILE_LIST 8
 #define AV1_OBU_FRAME 6
+#define AV1_OBU_FRAME_HEADER 3
 
 #define FF_PROFILE_AV1_MAIN 0
 #define FF_PROFILE_AV1_HIGH 1
 #define FF_PROFILE_AV1_PROFESSIONAL 2
 
+enum frame_type {
+	AV1_KEY_FRAME,
+	AV1_INTER_FRAME,
+	AV1_INTRA_FRAME,
+	AV1_SWITCH_FRAME,
+};
+
 typedef struct AV1SequenceParameters {
 	uint8_t profile;
 	uint8_t level;
@@ -536,11 +544,45 @@ size_t obs_parse_av1_header(uint8_t **header, const uint8_t *data, size_t size)
 	return output.bytes.num;
 }
 
+static void compute_av1_keyframe_priority(const uint8_t *buf, bool *is_keyframe,
+					  int *priority)
+{
+	/* Skip if the packet already has a priority, e.g., assigned by the
+	 * encoder implementation (currently QSV/AMF). */
+	if (*priority)
+		return;
+
+	Av1GetBitContext gb;
+
+	init_get_bits8(&gb, buf, 1);
+
+	// show_existing_frame
+	if (get_bit1(&gb))
+		return;
+
+	enum frame_type type = get_bits(&gb, 2);
+	bool show_frame = get_bit1(&gb);
+
+	switch (type) {
+	case AV1_KEY_FRAME:
+		*is_keyframe = true;
+		*priority = 3;
+		break;
+	case AV1_INTER_FRAME:
+		*priority = show_frame ? 1 : 2;
+		break;
+	case AV1_INTRA_FRAME:
+		*priority = 3;
+		break;
+	case AV1_SWITCH_FRAME:
+		*priority = 2;
+		break;
+	}
+}
+
 static void serialize_av1_data(struct serializer *s, const uint8_t *data,
 			       size_t size, bool *is_keyframe, int *priority)
 {
-	(void)is_keyframe;
-	(void)priority;
 	uint8_t *buf = (uint8_t *)data;
 	uint8_t *end = (uint8_t *)data + size;
 
@@ -559,6 +601,11 @@ static void serialize_av1_data(struct serializer *s, const uint8_t *data,
 		case AV1_OBU_REDUNDANT_FRAME_HEADER:
 		case AV1_OBU_TILE_LIST:
 			break;
+		case AV1_OBU_FRAME:
+		case AV1_OBU_FRAME_HEADER:
+			compute_av1_keyframe_priority(buf + start_pos,
+						      is_keyframe, priority);
+			/* Falls through. */
 		default:
 			s_write(s, buf, len);
 			size += len;