diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2020-07-13 14:58:21 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2020-07-14 15:51:38 -0700 |
commit | 48dae516a3fadc46eaf3228eb519728e2a3961e6 (patch) | |
tree | 538ed656f5b5a6eb2eaf26c7ba1fe76c7c22f041 /src | |
parent | 7da36aa7d4d40d4303dc702aa42347711a5fff81 (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.
Diffstat (limited to 'src')
-rw-r--r-- | src/rmd_encode_image_buffer.c | 47 | ||||
-rw-r--r-- | src/rmd_types.h | 1 |
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> |