+// SMV JPEG just stacks several output frames into one JPEG picture
+// we handle that by setting up the cropping parameters appropriately
+static int smv_process_frame(AVCodecContext *avctx, AVFrame *frame)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ int ret;
+
+ if (s->smv_next_frame > 0) {
+ av_assert0(s->smv_frame->buf[0]);
+ av_frame_unref(frame);
+ ret = av_frame_ref(frame, s->smv_frame);
+ if (ret < 0)
+ return ret;
+ } else {
+ av_assert0(frame->buf[0]);
+ av_frame_unref(s->smv_frame);
+ ret = av_frame_ref(s->smv_frame, frame);
+ if (ret < 0)
+ return ret;
+ }
+
+ av_assert0((s->smv_next_frame + 1) * avctx->height <= avctx->coded_height);
+
+ frame->width = avctx->coded_width;
+ frame->height = avctx->coded_height;
+ frame->crop_top = FFMIN(s->smv_next_frame * avctx->height, frame->height);
+ frame->crop_bottom = frame->height - (s->smv_next_frame + 1) * avctx->height;
+
+ s->smv_next_frame = (s->smv_next_frame + 1) % s->smv_frames_per_jpeg;
+
+ if (s->smv_next_frame == 0)
+ av_frame_unref(s->smv_frame);
+
+ return 0;
+}
+
+static int mjpeg_get_packet(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ int ret;
+
+ av_packet_unref(s->pkt);
+ ret = ff_decode_get_packet(avctx, s->pkt);
+ if (ret < 0)
+ return ret;
+
+#if CONFIG_SP5X_DECODER || CONFIG_AMV_DECODER
+ if (avctx->codec_id == AV_CODEC_ID_SP5X ||
+ avctx->codec_id == AV_CODEC_ID_AMV) {
+ ret = ff_sp5x_process_packet(avctx, s->pkt);
+ if (ret < 0)
+ return ret;
+ }
+#endif
+
+ s->buf_size = s->pkt->size;
+
+ return 0;
+}
+
+int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame)