mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
omx: Use the EOS flag to handle flushing at the end
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. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
dad7a9c7c0
commit
57ec83e424
@ -220,7 +220,7 @@ typedef struct OMXCodecContext {
|
|||||||
|
|
||||||
int mutex_cond_inited;
|
int mutex_cond_inited;
|
||||||
|
|
||||||
int num_in_frames, num_out_frames;
|
int eos_sent, got_eos;
|
||||||
|
|
||||||
uint8_t *output_buf;
|
uint8_t *output_buf;
|
||||||
int output_buf_size;
|
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);
|
av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
|
||||||
return AVERROR_UNKNOWN;
|
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) {
|
while (!*got_packet && ret == 0 && !s->got_eos) {
|
||||||
// Only wait for output if flushing and not all frames have been output
|
// 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,
|
buffer = get_buffer(&s->output_mutex, &s->output_cond,
|
||||||
&s->num_done_out_buffers, s->done_out_buffers,
|
&s->num_done_out_buffers, s->done_out_buffers,
|
||||||
!frame && s->num_out_frames < s->num_in_frames);
|
!frame);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
break;
|
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 (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) {
|
if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
|
||||||
avctx->extradata_size = 0;
|
avctx->extradata_size = 0;
|
||||||
@ -811,8 +829,6 @@ static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
|||||||
avctx->extradata_size += buffer->nFilledLen;
|
avctx->extradata_size += buffer->nFilledLen;
|
||||||
memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
} else {
|
} else {
|
||||||
if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME)
|
|
||||||
s->num_out_frames++;
|
|
||||||
if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) {
|
if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) {
|
||||||
// If the output packet isn't preallocated, just concatenate everything in our
|
// If the output packet isn't preallocated, just concatenate everything in our
|
||||||
// own buffer
|
// own buffer
|
||||||
|
Loading…
Reference in New Issue
Block a user