return profile > V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
 }
 
+static void coda_decoder_drop_used_metas(struct coda_ctx *ctx)
+{
+       struct coda_buffer_meta *meta, *tmp;
+
+       /*
+        * All metas that end at or before the RD pointer (fifo out),
+        * are now consumed by the VPU and should be released.
+        */
+       spin_lock(&ctx->buffer_meta_lock);
+       list_for_each_entry_safe(meta, tmp, &ctx->buffer_meta_list, list) {
+               if (ctx->bitstream_fifo.kfifo.out >= meta->end) {
+                       coda_dbg(2, ctx, "releasing meta: seq=%d start=%d end=%d\n",
+                                meta->sequence, meta->start, meta->end);
+
+                       list_del(&meta->list);
+                       ctx->num_metas--;
+                       ctx->first_frame_sequence++;
+                       kfree(meta);
+               }
+       }
+       spin_unlock(&ctx->buffer_meta_lock);
+}
+
 static int __coda_decoder_seq_init(struct coda_ctx *ctx)
 {
        struct coda_q_data *q_data_src, *q_data_dst;
        }
        ctx->sequence_offset = ~0U;
        ctx->initialized = 1;
+       ctx->first_frame_sequence = 0;
 
        /* Update kfifo out pointer from coda bitstream read pointer */
        coda_kfifo_sync_from_device(ctx);
 
+       /*
+        * After updating the read pointer, we need to check if
+        * any metas are consumed and should be released.
+        */
+       coda_decoder_drop_used_metas(ctx);
+
        if (coda_read(dev, CODA_RET_DEC_SEQ_SUCCESS) == 0) {
                v4l2_err(&dev->v4l2_dev,
                        "CODA_COMMAND_SEQ_INIT failed, error code = 0x%x\n",
                v4l2_err(&dev->v4l2_dev,
                         "decoded frame index out of range: %d\n", decoded_idx);
        } else {
+               int sequence;
+
                decoded_frame = &ctx->internal_frames[decoded_idx];
 
                val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM);
                if (ctx->sequence_offset == -1)
                        ctx->sequence_offset = val;
-               val -= ctx->sequence_offset;
+
+               sequence = val + ctx->first_frame_sequence
+                              - ctx->sequence_offset;
                spin_lock(&ctx->buffer_meta_lock);
                if (!list_empty(&ctx->buffer_meta_list)) {
                        meta = list_first_entry(&ctx->buffer_meta_list,
                         * should be enough to detect most errors and saves us
                         * from doing different things based on the format.
                         */
-                       if ((val & 0xffff) != (meta->sequence & 0xffff)) {
+                       if ((sequence & 0xffff) != (meta->sequence & 0xffff)) {
                                v4l2_err(&dev->v4l2_dev,
                                         "sequence number mismatch (%d(%d) != %d)\n",
-                                        val, ctx->sequence_offset,
+                                        sequence, ctx->sequence_offset,
                                         meta->sequence);
                        }
                        decoded_frame->meta = *meta;
                        v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n");
                        memset(&decoded_frame->meta, 0,
                               sizeof(struct coda_buffer_meta));
-                       decoded_frame->meta.sequence = val;
+                       decoded_frame->meta.sequence = sequence;
                        decoded_frame->meta.last = false;
                        ctx->sequence_offset++;
                }