Skip to content

Commit 44b8a97

Browse files
committed
Fixing the erratic live MP4 feed, caching the active font (a must for
dynamic OSDs with stable attributes)
1 parent ac9fdf7 commit 44b8a97

3 files changed

Lines changed: 38 additions & 27 deletions

File tree

src/fmt/mp4.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
#include "mp4.h"
22

33
uint32_t default_sample_size = 40000;
4+
uint32_t last_fragment_duration, timescale;
45

5-
unsigned int aud_samplerate = 0, aud_framesize = 0;
6+
unsigned int aud_samplerate = 0;
67
unsigned short aud_bitrate = 0;
78
char aud_channels = 0, aud_codec = 0, vid_framerate = 30;
89
short vid_width = 1920, vid_height = 1080;
@@ -42,8 +43,8 @@ enum BufError create_header(char is_h265) {
4243
moov_info.horizontal_resolution = 0x00480000; // 72 dpi
4344
moov_info.vertical_resolution = 0x00480000; // 72 dpi
4445
moov_info.creation_time = 0;
45-
moov_info.timescale =
46-
default_sample_size * vid_framerate;
46+
timescale = default_sample_size * vid_framerate;
47+
moov_info.timescale = timescale;
4748
moov_info.sps = buf_sps;
4849
moov_info.sps_length = buf_sps_len;
4950
moov_info.pps = buf_pps;
@@ -66,13 +67,6 @@ void mp4_set_config(short width, short height, char framerate, char acodec,
6667
aud_bitrate = bitrate;
6768
aud_channels = channels;
6869
aud_samplerate = srate;
69-
if (aud_samplerate > 0) {
70-
aud_framesize =
71-
(aud_samplerate >= 32000 ? 144 : 72) *
72-
(aud_bitrate * 1000) /
73-
aud_samplerate;
74-
} else aud_framesize = 384;
75-
7670
}
7771

7872
void mp4_set_sps(const char *nal_data, const uint32_t nal_len, char is_h265) {
@@ -95,6 +89,7 @@ void mp4_set_vps(const char *nal_data, const uint32_t nal_len) {
9589

9690
enum BufError mp4_set_slice(const char *nal_data, const uint32_t nal_len,
9791
char is_iframe) {
92+
uint64_t aud_ticks;
9893
enum BufError err;
9994

10095
struct SampleInfo samples_info[2];
@@ -103,8 +98,12 @@ enum BufError mp4_set_slice(const char *nal_data, const uint32_t nal_len,
10398
samples_info[0].duration = default_sample_size;
10499
samples_info[0].flags = is_iframe ? 0 : 65536;
105100
samples_info[1].size = buf_aud.offset;
106-
samples_info[1].duration = default_sample_size *
107-
buf_aud.offset / (aud_bitrate * 25 / 6);
101+
if (aud_bitrate > 0)
102+
aud_ticks = ((uint64_t)(buf_aud.offset << 3) * timescale) /
103+
(aud_bitrate * 1000);
104+
samples_info[1].duration = (uint32_t)aud_ticks;
105+
last_fragment_duration =
106+
MAX(samples_info[1].duration, samples_info[0].duration);
108107

109108
buf_moof.offset = 0;
110109
err = write_moof(
@@ -113,7 +112,7 @@ enum BufError mp4_set_slice(const char *nal_data, const uint32_t nal_len,
113112
chk_err;
114113

115114
buf_mdat.offset = 0;
116-
err = write_mdat(&buf_mdat, nal_data, nal_len,
115+
err = write_mdat(&buf_mdat, nal_data, nal_len,
117116
buf_aud.buf, buf_aud.offset);
118117
chk_err;
119118

@@ -145,7 +144,7 @@ enum BufError mp4_set_state(struct Mp4State *state) {
145144
state->base_media_decode_time);
146145
chk_err state->sequence_number++;
147146
state->base_data_offset += buf_moof.offset + buf_mdat.offset;
148-
state->base_media_decode_time += state->default_sample_duration;
147+
state->base_media_decode_time += last_fragment_duration;
149148
return BUF_OK;
150149
}
151150

@@ -168,4 +167,4 @@ enum BufError mp4_get_moof(struct BitBuf *ptr) {
168167
ptr->size = buf_moof.size;
169168
ptr->offset = buf_moof.offset;
170169
return BUF_OK;
171-
}
170+
}

src/fmt/mp4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ enum BufError mp4_set_state(struct Mp4State *state);
3939

4040
enum BufError mp4_get_header(struct BitBuf *ptr);
4141
enum BufError mp4_get_moof(struct BitBuf *ptr);
42-
enum BufError mp4_get_mdat(struct BitBuf *ptr);
42+
enum BufError mp4_get_mdat(struct BitBuf *ptr);

src/text.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
const double inv255 = 1.0 / 255.0;
44

5+
static SFT_Font *cachedFont = NULL;
6+
static char cachedFontPath[256] = "";
7+
static double cachedFontSize = -1.0;
8+
59
SFT sft;
610
SFT_Image canvas;
711
SFT_LMetrics lmtx;
812
hal_bitmap bitmap;
913

10-
int utf8_to_utf32(const unsigned char *utf8,
14+
int utf8_to_utf32(const unsigned char *utf8,
1115
unsigned int *utf32, int max)
1216
{
1317
unsigned int c;
@@ -87,26 +91,35 @@ void text_copy_rendered(SFT_Image *dest, const SFT_Image *source, int x0, int y0
8791

8892
int text_load_font(SFT *sft, const char *path, double size, SFT_LMetrics *lmtx)
8993
{
90-
SFT_Font *font = sft_loadfile(path);
91-
if (font == NULL)
92-
HAL_ERROR("text", "sft_loadfile failed");
93-
sft->font = font;
94+
if (!cachedFont || cachedFontSize != size || !EQUALS(cachedFontPath, path)) {
95+
if (cachedFont)
96+
sft_freefont(cachedFont);
97+
cachedFont = sft_loadfile(path);
98+
if (!cachedFont)
99+
HAL_ERROR("text", "Unable to load font file '%s'!", path);
100+
strncpy(cachedFontPath, path, sizeof(cachedFontPath));
101+
cachedFontPath[sizeof(cachedFontPath) - 1] = '\0';
102+
cachedFontSize = size;
103+
}
104+
105+
sft->font = cachedFont;
94106
sft->xScale = size;
95107
sft->yScale = size;
96108
sft->xOffset = 0.0;
97109
sft->yOffset = 0.0;
98110
sft->flags = SFT_DOWNWARD_Y;
99111
if (sft_lmetrics(sft, lmtx) < 0)
100-
HAL_ERROR("text", "sft_lmetrics failed");
112+
HAL_ERROR("text", "Unable to read font metrics for '%s' (size %.2f)!", path, size);
113+
101114
return EXIT_SUCCESS;
102115
}
103116

104117
int text_load_glyph(const SFT *sft, SFT_UChar codepoint, SFT_Glyph *glyph, SFT_GMetrics *metrics)
105118
{
106119
if (sft_lookup(sft, codepoint, glyph) < 0)
107-
HAL_ERROR("text", "sft_lookup failed");
120+
HAL_ERROR("text", "Cannot find glyph for codepoint U+%04X!", codepoint);
108121
if (sft_gmetrics(sft, *glyph, metrics) < 0)
109-
HAL_ERROR("text", "sft_gmetrics failed");
122+
HAL_ERROR("text", "Cannot read metrics for glyph U+%04X!", codepoint);
110123
return EXIT_SUCCESS;
111124
}
112125

@@ -153,7 +166,7 @@ void text_dim_rendered(double *margin, double *height, double *width, const char
153166
*width = MAX(*width, lwidth) + 2 * *margin;
154167
}
155168

156-
hal_bitmap text_create_rendered(const char *font, double size, const char *text,
169+
hal_bitmap text_create_rendered(const char *font, double size, const char *text,
157170
int color, int outline, double thick)
158171
{
159172
text_load_font(&sft, font, size, &lmtx);
@@ -212,6 +225,5 @@ noOutline:;
212225
bitmap.dim.height = canvas.height;
213226
bitmap.data = canvas.pixels;
214227

215-
sft_freefont(sft.font);
216228
return bitmap;
217-
}
229+
}

0 commit comments

Comments
 (0)