* Also append a start code 000001ff at the end to trigger
  * the ESPARSER interrupt.
  */
-static u32 esparser_pad_start_code(struct vb2_buffer *vb)
+static u32 esparser_pad_start_code(struct amvdec_core *core, struct vb2_buffer *vb)
 {
        u32 payload_size = vb2_get_plane_payload(vb, 0);
        u32 pad_size = 0;
-       u8 *vaddr = vb2_plane_vaddr(vb, 0) + payload_size;
+       u8 *vaddr = vb2_plane_vaddr(vb, 0);
 
        if (payload_size < ESPARSER_MIN_PACKET_SIZE) {
                pad_size = ESPARSER_MIN_PACKET_SIZE - payload_size;
-               memset(vaddr, 0, pad_size);
+               memset(vaddr + payload_size, 0, pad_size);
        }
 
-       memset(vaddr + pad_size, 0, SEARCH_PATTERN_LEN);
-       vaddr[pad_size]     = 0x00;
-       vaddr[pad_size + 1] = 0x00;
-       vaddr[pad_size + 2] = 0x01;
-       vaddr[pad_size + 3] = 0xff;
+       if ((payload_size + pad_size + SEARCH_PATTERN_LEN) >
+                                               vb2_plane_size(vb, 0)) {
+               dev_warn(core->dev, "%s: unable to pad start code\n", __func__);
+               return pad_size;
+       }
+
+       memset(vaddr + payload_size + pad_size, 0, SEARCH_PATTERN_LEN);
+       vaddr[payload_size + pad_size]     = 0x00;
+       vaddr[payload_size + pad_size + 1] = 0x00;
+       vaddr[payload_size + pad_size + 2] = 0x01;
+       vaddr[payload_size + pad_size + 3] = 0xff;
 
        return pad_size;
 }
        int ret;
        struct vb2_buffer *vb = &vbuf->vb2_buf;
        struct amvdec_core *core = sess->core;
-       struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
-       u32 num_dst_bufs = 0;
        u32 payload_size = vb2_get_plane_payload(vb, 0);
        dma_addr_t phy = vb2_dma_contig_plane_dma_addr(vb, 0);
        u32 offset;
        u32 pad_size;
 
-       if (codec_ops->num_pending_bufs)
-               num_dst_bufs = codec_ops->num_pending_bufs(sess);
-
-       num_dst_bufs += v4l2_m2m_num_dst_bufs_ready(sess->m2m_ctx);
-
-       if (esparser_vififo_get_free_space(sess) < payload_size ||
-           atomic_read(&sess->esparser_queued_bufs) >= num_dst_bufs)
+       if (esparser_vififo_get_free_space(sess) < payload_size)
                return -EAGAIN;
 
        v4l2_m2m_src_buf_remove_by_buf(sess->m2m_ctx, vbuf);
 
        offset = esparser_get_offset(sess);
 
-       amvdec_add_ts_reorder(sess, vb->timestamp, offset);
-       dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X\n",
-               vb->timestamp, payload_size, offset);
+       amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+       dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
+               vb->timestamp, payload_size, offset, vbuf->flags);
+
+       vbuf->flags = 0;
+       vbuf->field = V4L2_FIELD_NONE;
+       vbuf->sequence = sess->sequence_out++;
 
-       pad_size = esparser_pad_start_code(vb);
+       pad_size = esparser_pad_start_code(core, vb);
        ret = esparser_write_data(core, phy, payload_size + pad_size);
 
        if (ret <= 0) {
                return 0;
        }
 
-       /* We need to wait until we parse the first keyframe.
-        * All buffers prior to the first keyframe must be dropped.
-        */
-       if (!sess->keyframe_found)
-               usleep_range(1000, 2000);
-
-       if (sess->keyframe_found)
-               atomic_inc(&sess->esparser_queued_bufs);
-       else
-               amvdec_remove_ts(sess, vb->timestamp);
-
-       vbuf->flags = 0;
-       vbuf->field = V4L2_FIELD_NONE;
+       atomic_inc(&sess->esparser_queued_bufs);
        v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 
        return 0;
 
 {
        const struct amvdec_format *fmt_out = sess->fmt_out;
        unsigned int buffers_total = q->num_buffers + *num_buffers;
+       u32 min_buf_capture = v4l2_ctrl_g_ctrl(sess->ctrl_min_buf_capture);
 
+       if (q->num_buffers + *num_buffers < min_buf_capture)
+               *num_buffers = min_buf_capture - q->num_buffers;
        if (is_reqbufs && buffers_total < fmt_out->min_buffers)
                *num_buffers = fmt_out->min_buffers - q->num_buffers;
        if (buffers_total > fmt_out->max_buffers)
        if (*num_planes) {
                switch (q->type) {
                case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-                       if (*num_planes != 1 || sizes[0] < output_size)
+                       if (*num_planes != 1 ||
+                           sizes[0] < sess->src_buffer_size)
                                return -EINVAL;
                        break;
                case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
 
        switch (q->type) {
        case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
-               sizes[0] = amvdec_get_output_size(sess);
+               sizes[0] = sess->src_buffer_size;
                *num_planes = 1;
                break;
        case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
                return -EINVAL;
        }
 
+       sess->changed_format = 1;
        return 0;
 }
 
 
        v4l2_m2m_buf_queue(m2m_ctx, vbuf);
 
-       if (!sess->streamon_out || !sess->streamon_cap)
+       if (!sess->streamon_out)
                return;
 
-       if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+       if (sess->streamon_cap &&
+           vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
            vdec_codec_needs_recycle(sess))
                vdec_queue_recycle(sess, vb);
 
        else
                sess->streamon_cap = 1;
 
-       if (!sess->streamon_out || !sess->streamon_cap)
+       if (!sess->streamon_out)
                return 0;
 
        if (sess->status == STATUS_NEEDS_RESUME &&
-           q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+           q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+           sess->changed_format) {
                codec_ops->resume(sess);
                sess->status = STATUS_RUNNING;
                return 0;
        }
 
+       if (sess->status == STATUS_RUNNING ||
+           sess->status == STATUS_NEEDS_RESUME ||
+           sess->status == STATUS_INIT)
+               return 0;
+
        sess->vififo_size = SIZE_VIFIFO;
        sess->vififo_vaddr =
                dma_alloc_coherent(sess->core->dev, sess->vififo_size,
                goto vififo_free;
 
        sess->sequence_cap = 0;
+       sess->sequence_out = 0;
        if (vdec_codec_needs_recycle(sess))
                sess->recycle_thread = kthread_run(vdec_recycle_thread, sess,
                                                   "vdec_recycle");
 
-       sess->status = STATUS_RUNNING;
+       sess->status = STATUS_INIT;
        core->cur_sess = sess;
-
+       schedule_work(&sess->esparser_queue_work);
        return 0;
 
 vififo_free:
        struct vb2_v4l2_buffer *buf;
 
        if (sess->status == STATUS_RUNNING ||
+           sess->status == STATUS_INIT ||
            (sess->status == STATUS_NEEDS_RESUME &&
             (!sess->streamon_out || !sess->streamon_cap))) {
                if (vdec_codec_needs_recycle(sess))
        struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
        struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
        const struct amvdec_format *fmts = sess->core->platform->formats;
-       const struct amvdec_format *fmt_out;
+       const struct amvdec_format *fmt_out = NULL;
+       u32 output_size = 0;
 
        memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
        memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
 
-       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+       switch (f->type) {
+       case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
                fmt_out = find_format(fmts, size, pixmp->pixelformat);
                if (!fmt_out) {
                        pixmp->pixelformat = V4L2_PIX_FMT_MPEG2;
                        fmt_out = find_format(fmts, size, pixmp->pixelformat);
                }
+               break;
+       case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+               fmt_out = sess->fmt_out;
+               break;
+       default:
+               return NULL;
+       }
 
-               pfmt[0].sizeimage =
-                       get_output_size(pixmp->width, pixmp->height);
+       pixmp->width  = clamp(pixmp->width,  (u32)256, fmt_out->max_width);
+       pixmp->height = clamp(pixmp->height, (u32)144, fmt_out->max_height);
+       output_size = get_output_size(pixmp->width, pixmp->height);
+
+       if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+               if (!pfmt[0].sizeimage)
+                       pfmt[0].sizeimage = sess->src_buffer_size;
                pfmt[0].bytesperline = 0;
                pixmp->num_planes = 1;
        } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 
                memset(pfmt[1].reserved, 0, sizeof(pfmt[1].reserved));
                if (pixmp->pixelformat == V4L2_PIX_FMT_NV12M) {
-                       pfmt[0].sizeimage =
-                               get_output_size(pixmp->width, pixmp->height);
+                       pfmt[0].sizeimage = output_size;
                        pfmt[0].bytesperline = ALIGN(pixmp->width, 64);
 
-                       pfmt[1].sizeimage =
-                             get_output_size(pixmp->width, pixmp->height) / 2;
+                       pfmt[1].sizeimage = output_size / 2;
                        pfmt[1].bytesperline = ALIGN(pixmp->width, 64);
                        pixmp->num_planes = 2;
                } else if (pixmp->pixelformat == V4L2_PIX_FMT_YUV420M) {
-                       pfmt[0].sizeimage =
-                               get_output_size(pixmp->width, pixmp->height);
+                       pfmt[0].sizeimage = output_size;
                        pfmt[0].bytesperline = ALIGN(pixmp->width, 64);
 
-                       pfmt[1].sizeimage =
-                             get_output_size(pixmp->width, pixmp->height) / 4;
+                       pfmt[1].sizeimage = output_size / 4;
                        pfmt[1].bytesperline = ALIGN(pixmp->width, 64) / 2;
 
-                       pfmt[2].sizeimage =
-                             get_output_size(pixmp->width, pixmp->height) / 4;
+                       pfmt[2].sizeimage = output_size / 2;
                        pfmt[2].bytesperline = ALIGN(pixmp->width, 64) / 2;
                        pixmp->num_planes = 3;
                }
-       } else {
-               return NULL;
        }
 
-       pixmp->width  = clamp(pixmp->width,  (u32)256, fmt_out->max_width);
-       pixmp->height = clamp(pixmp->height, (u32)144, fmt_out->max_height);
-
        if (pixmp->field == V4L2_FIELD_ANY)
                pixmp->field = V4L2_FIELD_NONE;
 
        orig_pixmp = *pixmp;
 
        fmt_out = vdec_try_fmt_common(sess, num_formats, f);
+       if (!fmt_out)
+               return -EINVAL;
 
        if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
                pixfmt_out = pixmp->pixelformat;
                sess->ycbcr_enc = pixmp->ycbcr_enc;
                sess->quantization = pixmp->quantization;
                sess->xfer_func = pixmp->xfer_func;
+               sess->src_buffer_size = pixmp->plane_fmt[0].sizeimage;
        }
 
        memset(&format, 0, sizeof(format));
        if (!(sess->streamon_out & sess->streamon_cap))
                return 0;
 
-       /* Currently not handled since we do not support dynamic resolution
-        * for MPEG2. We consider both queues streaming to mean that the
-        * decoding session is started
-        */
-       if (cmd->cmd == V4L2_DEC_CMD_START)
+       if (cmd->cmd == V4L2_DEC_CMD_START) {
+               v4l2_m2m_clear_state(sess->m2m_ctx);
+               sess->should_stop = 0;
                return 0;
+       }
 
        /* Should not happen */
        if (cmd->cmd != V4L2_DEC_CMD_STOP)
                return -EINVAL;
 
        dev_dbg(dev, "Received V4L2_DEC_CMD_STOP\n");
+
        sess->should_stop = 1;
 
-       vdec_wait_inactive(sess);
+       v4l2_m2m_mark_stopped(sess->m2m_ctx);
 
        if (codec_ops->drain) {
+               vdec_wait_inactive(sess);
                codec_ops->drain(sess);
        } else if (codec_ops->eos_sequence) {
                u32 len;
                const u8 *data = codec_ops->eos_sequence(&len);
 
                esparser_queue_eos(sess->core, data, len);
+               vdec_wait_inactive(sess);
        }
 
        return ret;
        sess->height = 720;
        sess->pixelaspect.numerator = 1;
        sess->pixelaspect.denominator = 1;
+       sess->src_buffer_size = SZ_1M;
 
        INIT_LIST_HEAD(&sess->timestamps);
        INIT_LIST_HEAD(&sess->bufs_recycle);
 
  * struct amvdec_timestamp - stores a src timestamp along with a VIFIFO offset
  *
  * @list: used to make lists out of this struct
- * @ts: timestamp
+ * @tc: timecode from the v4l2 buffer
+ * @ts: timestamp from the VB2 buffer
  * @offset: offset in the VIFIFO where the associated packet was written
+ * @flags: flags from the v4l2 buffer
+ * @used_count: times this timestamp was checked for a match with a dst buffer
  */
 struct amvdec_timestamp {
        struct list_head list;
+       struct v4l2_timecode tc;
        u64 ts;
        u32 offset;
+       u32 flags;
+       u32 used_count;
 };
 
 struct amvdec_session;
 
 enum amvdec_status {
        STATUS_STOPPED,
+       STATUS_INIT,
        STATUS_RUNNING,
        STATUS_NEEDS_RESUME,
 };
  * @ctrl_min_buf_capture: V4L2 control V4L2_CID_MIN_BUFFERS_FOR_CAPTURE
  * @fmt_out: vdec pixel format for the OUTPUT queue
  * @pixfmt_cap: V4L2 pixel format for the CAPTURE queue
+ * @src_buffer_size: size in bytes of the OUTPUT buffers' only plane
  * @width: current picture width
  * @height: current picture height
  * @colorspace: current colorspace
 
        const struct amvdec_format *fmt_out;
        u32 pixfmt_cap;
+       u32 src_buffer_size;
 
        u32 width;
        u32 height;
        struct work_struct esparser_queue_work;
 
        unsigned int streamon_cap, streamon_out;
-       unsigned int sequence_cap;
+       unsigned int sequence_cap, sequence_out;
        unsigned int should_stop;
        unsigned int keyframe_found;
        unsigned int num_dst_bufs;
+       unsigned int changed_format;
 
        u8 canvas_alloc[MAX_CANVAS];
        u32 canvas_num;
 
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);
 
-void amvdec_add_ts_reorder(struct amvdec_session *sess, u64 ts, u32 offset)
+void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
-       struct amvdec_timestamp *new_ts, *tmp;
+       struct amvdec_timestamp *new_ts;
        unsigned long flags;
 
-       new_ts = kmalloc(sizeof(*new_ts), GFP_KERNEL);
+       new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
        new_ts->ts = ts;
+       new_ts->tc = tc;
        new_ts->offset = offset;
+       new_ts->flags = vbuf_flags;
 
        spin_lock_irqsave(&sess->ts_spinlock, flags);
-
-       if (list_empty(&sess->timestamps))
-               goto add_tail;
-
-       list_for_each_entry(tmp, &sess->timestamps, list) {
-               if (ts <= tmp->ts) {
-                       list_add_tail(&new_ts->list, &tmp->list);
-                       goto unlock;
-               }
-       }
-
-add_tail:
        list_add_tail(&new_ts->list, &sess->timestamps);
-unlock:
        spin_unlock_irqrestore(&sess->ts_spinlock, flags);
 }
-EXPORT_SYMBOL_GPL(amvdec_add_ts_reorder);
+EXPORT_SYMBOL_GPL(amvdec_add_ts);
 
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts)
 {
 
 static void dst_buf_done(struct amvdec_session *sess,
                         struct vb2_v4l2_buffer *vbuf,
-                        u32 field,
-                        u64 timestamp)
+                        u32 field, u64 timestamp,
+                        struct v4l2_timecode timecode, u32 flags)
 {
        struct device *dev = sess->core->dev_dec;
        u32 output_size = amvdec_get_output_size(sess);
 
        vbuf->vb2_buf.timestamp = timestamp;
        vbuf->sequence = sess->sequence_cap++;
+       vbuf->flags = flags;
+       vbuf->timecode = timecode;
 
        if (sess->should_stop &&
-           atomic_read(&sess->esparser_queued_bufs) <= 2) {
+           atomic_read(&sess->esparser_queued_bufs) <= 1) {
                const struct v4l2_event ev = { .type = V4L2_EVENT_EOS };
 
-               dev_dbg(dev, "Signaling EOS\n");
+               dev_dbg(dev, "Signaling EOS, sequence_cap = %u\n",
+                       sess->sequence_cap - 1);
                v4l2_event_queue_fh(&sess->fh, &ev);
                vbuf->flags |= V4L2_BUF_FLAG_LAST;
        } else if (sess->should_stop)
                dev_dbg(dev, "should_stop, %u bufs remain\n",
                        atomic_read(&sess->esparser_queued_bufs));
 
-       dev_dbg(dev, "Buffer %u done\n", vbuf->vb2_buf.index);
+       dev_dbg(dev, "Buffer %u done, ts = %llu, flags = %08X\n",
+               vbuf->vb2_buf.index, timestamp, flags);
        vbuf->field = field;
        v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
 
        struct device *dev = sess->core->dev_dec;
        struct amvdec_timestamp *tmp;
        struct list_head *timestamps = &sess->timestamps;
+       struct v4l2_timecode timecode;
        u64 timestamp;
+       u32 vbuf_flags;
        unsigned long flags;
 
        spin_lock_irqsave(&sess->ts_spinlock, flags);
 
        tmp = list_first_entry(timestamps, struct amvdec_timestamp, list);
        timestamp = tmp->ts;
+       timecode = tmp->tc;
+       vbuf_flags = tmp->flags;
        list_del(&tmp->list);
        kfree(tmp);
        spin_unlock_irqrestore(&sess->ts_spinlock, flags);
 
-       dst_buf_done(sess, vbuf, field, timestamp);
+       dst_buf_done(sess, vbuf, field, timestamp, timecode, vbuf_flags);
        atomic_dec(&sess->esparser_queued_bufs);
 }
 EXPORT_SYMBOL_GPL(amvdec_dst_buf_done);
        struct device *dev = sess->core->dev_dec;
        struct amvdec_timestamp *match = NULL;
        struct amvdec_timestamp *tmp, *n;
+       struct v4l2_timecode timecode = { 0 };
        u64 timestamp = 0;
+       u32 vbuf_flags = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&sess->ts_spinlock, flags);
 
        /* Look for our vififo offset to get the corresponding timestamp. */
        list_for_each_entry_safe(tmp, n, &sess->timestamps, list) {
-               s64 delta = (s64)offset - tmp->offset;
-
-               /* Offsets reported by codecs usually differ slightly,
-                * so we need some wiggle room.
-                * 4KiB being the minimum packet size, there is no risk here.
-                */
-               if (delta > (-1 * (s32)SZ_4K) && delta < SZ_4K) {
-                       match = tmp;
+               if (tmp->offset > offset) {
+                       /*
+                        * Delete any record that remained unused for 32 match
+                        * checks
+                        */
+                       if (tmp->used_count++ >= 32) {
+                               list_del(&tmp->list);
+                               kfree(tmp);
+                       }
                        break;
                }
 
-               if (!allow_drop)
-                       continue;
-
-               /* Delete any timestamp entry that appears before our target
-                * (not all src packets/timestamps lead to a frame)
-                */
-               if (delta > 0 || delta < -1 * (s32)sess->vififo_size) {
-                       atomic_dec(&sess->esparser_queued_bufs);
-                       list_del(&tmp->list);
-                       kfree(tmp);
-               }
+               match = tmp;
        }
 
        if (!match) {
-               dev_dbg(dev, "Buffer %u done but can't match offset (%08X)\n",
+               dev_err(dev, "Buffer %u done but can't match offset (%08X)\n",
                        vbuf->vb2_buf.index, offset);
        } else {
                timestamp = match->ts;
+               timecode = match->tc;
+               vbuf_flags = match->flags;
                list_del(&match->list);
                kfree(match);
        }
        spin_unlock_irqrestore(&sess->ts_spinlock, flags);
 
-       dst_buf_done(sess, vbuf, field, timestamp);
+       dst_buf_done(sess, vbuf, field, timestamp, timecode, vbuf_flags);
        if (match)
                atomic_dec(&sess->esparser_queued_bufs);
 }
 
        v4l2_ctrl_s_ctrl(sess->ctrl_min_buf_capture, dpb_size);
 
-       /* Check if the capture queue is already configured well for our
+       /*
+        * Check if the capture queue is already configured well for our
         * usecase. If so, keep decoding with it and do not send the event
         */
-       if (sess->width == width &&
+       if (sess->streamon_cap &&
+           sess->width == width &&
            sess->height == height &&
            dpb_size <= sess->num_dst_bufs) {
                sess->fmt_out->codec_ops->resume(sess);
                return;
        }
 
+       sess->changed_format = 0;
        sess->width = width;
        sess->height = height;
        sess->status = STATUS_NEEDS_RESUME;
 
                                u32 offset, u32 field, bool allow_drop);
 
 /**
- * amvdec_add_ts_reorder() - Add a timestamp to the list in chronological order
+ * amvdec_add_ts() - Add a timestamp to the list
  *
  * @sess: current session
  * @ts: timestamp to add
  * @offset: offset in the VIFIFO where the associated packet was written
+ * @flags the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts_reorder(struct amvdec_session *sess, u64 ts, u32 offset);
+void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                  struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
 
 /**
 
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        }, {
                .pixfmt = V4L2_PIX_FMT_MPEG2,
                .min_buffers = 8,
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        },
 };
 
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        }, {
                .pixfmt = V4L2_PIX_FMT_MPEG2,
                .min_buffers = 8,
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        },
 };
 
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        }, {
                .pixfmt = V4L2_PIX_FMT_MPEG2,
                .min_buffers = 8,
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        },
 };
 
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        }, {
                .pixfmt = V4L2_PIX_FMT_MPEG2,
                .min_buffers = 8,
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        },
 };
 
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        }, {
                .pixfmt = V4L2_PIX_FMT_MPEG2,
                .min_buffers = 8,
                .codec_ops = &codec_mpeg12_ops,
                .firmware_path = "meson/vdec/gxl_mpeg12.bin",
                .pixfmts_cap = { V4L2_PIX_FMT_NV12M, V4L2_PIX_FMT_YUV420M, 0 },
+               .flags = V4L2_FMT_FLAG_COMPRESSED,
        },
 };