This avoids having to count the number of frames sent to the codec
and the number of output packets received; instead just wait until
the encoder returns a buffer with the EOS flag set.
This avoids potential (so far only theoretical) issues if an encoder
doesn't output exactly one packet per input frame.
---
libavcodec/omx.c | 30 +++++++++++++++++++++++-------
1 file changed, 23 insertions(+), 7 deletions(-)
diff --git a/libavcodec/omx.c b/libavcodec/omx.c
index 05c8743..f43e92a 100644
--- a/libavcodec/omx.c
+++ b/libavcodec/omx.c
@@ -220,7 +220,7 @@ typedef struct OMXCodecContext {
int mutex_cond_inited;
- int num_in_frames, num_out_frames;
+ int eos_sent, got_eos;
uint8_t *output_buf;
int output_buf_size;
@@ -791,17 +791,35 @@ static int omx_encode_frame(AVCodecContext *avctx,
AVPacket *pkt,
av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n",
err);
return AVERROR_UNKNOWN;
}
- s->num_in_frames++;
+ } else if (!s->eos_sent) {
+ buffer = get_buffer(&s->input_mutex, &s->input_cond,
+ &s->num_free_in_buffers, s->free_in_buffers, 1);
+
+ buffer->nFilledLen = 0;
+ buffer->nFlags = OMX_BUFFERFLAG_EOS;
+ buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
+ err = OMX_EmptyThisBuffer(s->handle, buffer);
+ if (err != OMX_ErrorNone) {
+ append_buffer(&s->input_mutex, &s->input_cond,
&s->num_free_in_buffers, s->free_in_buffers, buffer);
+ av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n",
err);
+ return AVERROR_UNKNOWN;
+ }
+ s->eos_sent = 1;
}
- while (!*got_packet && ret == 0) {
- // Only wait for output if flushing and not all frames have been output
+ while (!*got_packet && ret == 0 && !s->got_eos) {
+ // If not flushing, just poll the queue if there's finished packets.
+ // If flushing, do a blocking wait until we either get a completed
+ // packet, or get EOS.
buffer = get_buffer(&s->output_mutex, &s->output_cond,
&s->num_done_out_buffers, s->done_out_buffers,
- !frame && s->num_out_frames < s->num_in_frames);
+ !frame);
if (!buffer)
break;
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
+ s->got_eos = 1;
+
if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags &
AV_CODEC_FLAG_GLOBAL_HEADER) {
if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size +
buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
avctx->extradata_size = 0;
@@ -811,8 +829,6 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket
*pkt,
avctx->extradata_size += buffer->nFilledLen;
memset(avctx->extradata + avctx->extradata_size, 0,
AV_INPUT_BUFFER_PADDING_SIZE);
} else {
- if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME)
- s->num_out_frames++;
if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) {
// If the output packet isn't preallocated, just concatenate
everything in our
// own buffer
--
2.1.4
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel