forked from meetecho/janus-gateway
-
Notifications
You must be signed in to change notification settings - Fork 0
/
record.h
130 lines (120 loc) · 5.73 KB
/
record.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*! \file record.h
* \author Lorenzo Miniero <lorenzo@meetecho.com>
* \copyright GNU General Public License v3
* \brief Audio/Video recorder (headers)
* \details Implementation of a simple recorder utility that plugins
* can make use of to record audio/video frames to a Janus file. This
* file just saves RTP frames in a structured way, so that they can be
* post-processed later on to get a valid container file (e.g., a .opus
* file for Opus audio or a .webm file for VP8 video) and keep things
* simpler on the plugin and core side. Check the \ref recordings
* documentation for more details.
* \note If you want to record both audio and video, you'll have to use
* two different recorders. Any muxing in the same container will have
* to be done in the post-processing phase.
*
* \ingroup core
* \ref core
*/
#ifndef JANUS_RECORD_H
#define JANUS_RECORD_H
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mutex.h"
#include "refcount.h"
/*! \brief Media types we can record */
typedef enum janus_recorder_medium {
JANUS_RECORDER_AUDIO,
JANUS_RECORDER_VIDEO,
JANUS_RECORDER_DATA
} janus_recorder_medium;
#ifdef RECORD_MULTIPART
#define NB_MAX_FRAME_VIDEO 10000
#define NB_MAX_FRAME_AUDIO 1000000
#endif
/*! \brief Structure that represents a recorder */
typedef struct janus_recorder {
/*! \brief Absolute path to the directory where the recorder file is stored */
char *dir;
/*! \brief Filename of this recorder file */
char *filename;
#ifdef RECORD_MULTIPART
/*! initial filename */
char *initial_filename;
#endif
/*! \brief Recording file */
FILE *file;
/*! \brief Codec the packets to record are encoded in ("vp8", "vp9", "h264", "opus", "pcma", "pcmu", "g722") */
char *codec;
/*! \brief Codec-specific info (e.g., H.264 or VP9 profile) */
char *fmtp;
/*! \brief When the recording file has been created and started */
gint64 created, started;
/*! \brief Media this instance is recording */
janus_recorder_medium type;
/*! \brief Whether the recording contains end-to-end encrypted media or not */
gboolean encrypted;
/*! \brief Whether the info header for this recorder instance has already been written or not */
volatile int header;
/*! \brief Whether this recorder instance can be used for writing or not */
volatile int writable;
/*! \brief Mutex to lock/unlock this recorder instance */
janus_mutex mutex;
/*! \brief Atomic flag to check if this instance has been destroyed */
volatile gint destroyed;
/*! \brief Reference counter for this instance */
janus_refcount ref;
#ifdef RECORD_MULTIPART
/* counter for the indent file */
gint64 cptr_suffix_filename;
/* counter for the number of frames */
gint64 cptr_nb_frames;
#endif
} janus_recorder;
/*! \brief Initialize the recorder code
* @param[in] tempnames Whether the filenames should have a temporary extension, while saving, or not
* @param[in] extension Extension to add in case tempnames is true */
void janus_recorder_init(gboolean tempnames, const char *extension);
/*! \brief De-initialize the recorder code */
void janus_recorder_deinit(void);
/*! \brief Create a new recorder
* \note If no target directory is provided, the current directory will be used. If no filename
* is passed, a random filename will be used.
* @param[in] dir Path of the directory to save the recording into (will try to create it if it doesn't exist)
* @param[in] codec Codec the packets to record are encoded in ("vp8", "opus", "h264", "g711", "vp9")
* @param[in] filename Filename to use for the recording
* @returns A valid janus_recorder instance in case of success, NULL otherwise */
janus_recorder *janus_recorder_create(const char *dir, const char *codec, const char *filename);
/*! \brief Create a new recorder with additional info
* \note This is to allow adding more arguments to janus_recorder_create, but
* still keep janus_recorder_create in place for backwards compatibility.
* @param[in] dir Path of the directory to save the recording into (will try to create it if it doesn't exist)
* @param[in] codec Codec the packets to record are encoded in ("vp8", "opus", "h264", "g711", "vp9")
* @param[in] fmtp Codec-specific details (e.g., the H.264 or VP9 profile)
* @param[in] filename Filename to use for the recording
* @returns A valid janus_recorder instance in case of success, NULL otherwise */
janus_recorder *janus_recorder_create_full(const char *dir, const char *codec, const char *fmtp, const char *filename);
/*! \brief Mark this recorder as end-to-end encrypted (e.g., via Insertable Streams)
* \note This will only be possible BEFORE the first frame is written, as it needs to
* be reflected in the .mjr header: doing this after that will return an error. Also
* notice that an encrypted recording will NOT be processable with \c janus-pp-rec
* out of the box, since the post-processor will not have access to unencrypted media
* @param[in] recorder The janus_recorder instance to mark as encrypted
* @returns 0 in case of success, a negative integer otherwise */
int janus_recorder_encrypted(janus_recorder *recorder);
/*! \brief Save an RTP frame in the recorder
* @param[in] recorder The janus_recorder instance to save the frame to
* @param[in] buffer The frame data to save
* @param[in] length The frame data length
* @returns 0 in case of success, a negative integer otherwise */
int janus_recorder_save_frame(janus_recorder *recorder, char *buffer, uint length);
/*! \brief Close the recorder
* @param[in] recorder The janus_recorder instance to close
* @returns 0 in case of success, a negative integer otherwise */
int janus_recorder_close(janus_recorder *recorder);
/*! \brief Destroy the recorder instance
* @param[in] recorder The janus_recorder instance to destroy */
void janus_recorder_destroy(janus_recorder *recorder);
#endif