summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-07-13 14:58:21 -0700
committerVito Caputo <vcaputo@pengaru.com>2020-07-14 15:51:38 -0700
commit48dae516a3fadc46eaf3228eb519728e2a3961e6 (patch)
tree538ed656f5b5a6eb2eaf26c7ba1fe76c7c22f041
parent7da36aa7d4d40d4303dc702aa42347711a5fff81 (diff)
encode_image_buffer: duplicate missed frames
When the encoder finds the encoded - captured frameno delta > 1 it needs to fill the gap somehow. With how things are currently architected, the old yuv countents are gone so there's only the current frame available for filling. The newer theoraenc.h API exposes a theora_control() parameter for this purpose, so I've also added a theoraenc.h include implicitly bumping the libtheora dependency. But by now it shouldn't matter, and the rest of rmd should probably get updated to use the new theora API eventually anyways. I'm still uncertain what role pdata->avd will play in the long-run, but leaving its maintenance for now.
-rw-r--r--src/rmd_encode_image_buffer.c47
-rw-r--r--src/rmd_types.h1
2 files changed, 30 insertions, 18 deletions
diff --git a/src/rmd_encode_image_buffer.c b/src/rmd_encode_image_buffer.c
index f5e8b36..57ac5ce 100644
--- a/src/rmd_encode_image_buffer.c
+++ b/src/rmd_encode_image_buffer.c
@@ -34,14 +34,21 @@
void *rmdEncodeImageBuffer(ProgData *pdata) {
- unsigned int encode_frameno = 0;
+ unsigned int encode_frameno = 0, last_encode_frameno = 0;
rmdThreadsSetName("rmdEncodeImages");
pdata->th_encoding_clean = 0;
while (pdata->running) {
- EncData *enc_data = pdata->enc_data;
+ EncData *enc_data = pdata->enc_data;
+ unsigned int n_frames;
+ int r;
+
+ pthread_mutex_lock(&pdata->pause_mutex);
+ while (pdata->paused)
+ pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
+ pthread_mutex_unlock(&pdata->pause_mutex);
pthread_mutex_lock(&pdata->img_buff_ready_mutex);
while (pdata->running && encode_frameno >= pdata->capture_frameno)
@@ -49,25 +56,29 @@ void *rmdEncodeImageBuffer(ProgData *pdata) {
encode_frameno = pdata->capture_frameno;
pthread_mutex_unlock(&pdata->img_buff_ready_mutex);
- pthread_mutex_lock(&pdata->pause_mutex);
- while (pdata->paused)
- pthread_cond_wait(&pdata->pause_cond, &pdata->pause_mutex);
- pthread_mutex_unlock(&pdata->pause_mutex);
-
pthread_mutex_lock(&pdata->yuv_mutex);
- if (theora_encode_YUVin(&enc_data->m_th_st, &enc_data->yuv)) {
+ r = theora_encode_YUVin(&enc_data->m_th_st, &enc_data->yuv);
+ pthread_mutex_unlock(&pdata->yuv_mutex);
+ if (r) {
fprintf(stderr, "Encoder not ready!\n");
- pthread_mutex_unlock(&pdata->yuv_mutex);
- } else {
- pthread_mutex_unlock(&pdata->yuv_mutex);
-
- if (theora_encode_packetout(&enc_data->m_th_st, 0, &enc_data->m_ogg_pckt1) == 1) {
- pthread_mutex_lock(&pdata->libogg_mutex);
- ogg_stream_packetin(&enc_data->m_ogg_ts, &enc_data->m_ogg_pckt1);
- pdata->avd += pdata->frametime;
- pthread_mutex_unlock(&pdata->libogg_mutex);
- }
+ continue;
}
+
+ n_frames = encode_frameno - last_encode_frameno;
+ if (n_frames > 1)
+ theora_control( &enc_data->m_th_st,
+ TH_ENCCTL_SET_DUP_COUNT,
+ (void *)&(int){n_frames - 1},
+ sizeof(int));
+
+ while (theora_encode_packetout(&enc_data->m_th_st, 0, &enc_data->m_ogg_pckt1) > 0) {
+ pthread_mutex_lock(&pdata->libogg_mutex);
+ ogg_stream_packetin(&enc_data->m_ogg_ts, &enc_data->m_ogg_pckt1);
+ pdata->avd += pdata->frametime;
+ pthread_mutex_unlock(&pdata->libogg_mutex);
+ }
+
+ last_encode_frameno = encode_frameno;
}
//last packet
diff --git a/src/rmd_types.h b/src/rmd_types.h
index 159434a..f01083c 100644
--- a/src/rmd_types.h
+++ b/src/rmd_types.h
@@ -33,6 +33,7 @@
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <theora/theora.h>
+#include <theora/theoraenc.h>
#include <vorbis/codec.h>
#include <vorbis/vorbisenc.h>
#include <ogg/ogg.h>
© All Rights Reserved