@@ -46,7 +46,7 @@
typedef struct FFBufferEntry {
AVBufferRef *ref;
- void *data;
+ const void *data;
size_t length;
int64_t pts, dts;
int flags;
@@ -476,27 +476,22 @@ fail:
// (due to us not reading/returning enough output buffers) and won't accept
// new input. (This wouldn't be an issue if MMAL input buffers always were
// complete frames - then the input buffer just would have to be big enough.)
-// If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
-static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
- int is_extradata)
+// Extradata (avpkt == NULL) is sent as MMAL_BUFFER_HEADER_FLAG_CONFIG.
+static int ffmmal_add_packet(AVCodecContext *avctx, const AVPacket *avpkt,
+ const uint8_t *data, int size)
{
MMALDecodeContext *ctx = avctx->priv_data;
AVBufferRef *buf = NULL;
- int size = 0;
- uint8_t *data = (uint8_t *)"";
- uint8_t *start;
+ const uint8_t *start;
int ret = 0;
- if (avpkt->size) {
- if (avpkt->buf) {
+ if (size) {
+ if (avpkt) {
buf = av_buffer_ref(avpkt->buf);
- size = avpkt->size;
- data = avpkt->data;
} else {
- buf = av_buffer_alloc(avpkt->size);
+ buf = av_buffer_alloc(size);
if (buf) {
- memcpy(buf->data, avpkt->data, avpkt->size);
- size = buf->size;
+ memcpy(buf->data, data, size);
data = buf->data;
}
}
@@ -504,9 +499,10 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
ret = AVERROR(ENOMEM);
goto done;
}
- if (!is_extradata)
+ if (avpkt)
ctx->packets_sent++;
} else {
+ data = "";
if (ctx->eos_sent)
goto done;
if (!ctx->packets_sent) {
@@ -529,7 +525,7 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
buffer->data = data;
buffer->length = FFMIN(size, ctx->decoder->input[0]->buffer_size);
- if (is_extradata)
+ if (!avpkt)
buffer->flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
if (data == start)
@@ -538,8 +534,10 @@ static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
data += buffer->length;
size -= buffer->length;
- buffer->pts = avpkt->pts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->pts;
- buffer->dts = avpkt->dts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->dts;
+ buffer->pts = !avpkt || avpkt->pts == AV_NOPTS_VALUE ?
+ MMAL_TIME_UNKNOWN : avpkt->pts;
+ buffer->dts = !avpkt || avpkt->dts == AV_NOPTS_VALUE ?
+ MMAL_TIME_UNKNOWN : avpkt->dts;
if (!size) {
buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
@@ -594,7 +592,7 @@ static int ffmmal_fill_input_port(AVCodecContext *avctx)
mbuffer->pts = buffer->pts;
mbuffer->dts = buffer->dts;
mbuffer->flags = buffer->flags;
- mbuffer->data = buffer->data;
+ mbuffer->data = (uint8_t*)buffer->data;
mbuffer->length = buffer->length;
mbuffer->user_data = buffer;
mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size;
@@ -776,16 +774,13 @@ static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame,
int ret = 0;
if (avctx->extradata_size && !ctx->extradata_sent) {
- AVPacket pkt = {0};
- av_init_packet(&pkt);
- pkt.data = avctx->extradata;
- pkt.size = avctx->extradata_size;
ctx->extradata_sent = 1;
- if ((ret = ffmmal_add_packet(avctx, &pkt, 1)) < 0)
+ if ((ret = ffmmal_add_packet(avctx, NULL, avctx->extradata,
+ avctx->extradata_size)) < 0)
return ret;
}
- if ((ret = ffmmal_add_packet(avctx, avpkt, 0)) < 0)
+ if ((ret = ffmmal_add_packet(avctx, avpkt, pkt->data, pkt->size)) < 0)
return ret;
if ((ret = ffmmal_fill_input_port(avctx)) < 0)
Up until now the function to add packets to the waiting buffers list uses an AVPacket as parameter; therefore extradata that is also sent once gets wrapped in an AVPacket. Yet this is unnecessary as the function does not really need a complete AVPacket, but mostly the data. Therefore this commit modifies the function to accept a pointer for the data and int for the size as well as the AVPacket* parameter, which is NULL for extradata. Furthermore, this commit adds const to the pointed to types if the data doesn't change. The MMAL_BUFFER_HEADER_T struct unfortunately uses uint8_t* for data that is not modified, necessitating a cast. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> --- These two commits are completely untested; I just hope they compile. Could please someone test them? Thanks in advance. This commit provides an alternative way to avoid AVPackets on the stack and av_init_packet; furthermore, this commit also aims to make this decoder compatible with receiving a const AVPacket*. libavcodec/mmaldec.c | 45 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 25 deletions(-)