|
|
|
@ -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; |
|
|
|
@ -808,17 +808,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; |
|
|
|
@ -828,8 +846,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
|
|
|
|
|