Re: [FFmpeg-devel] [PATCH 7/9] mjpegdec: convert to receive_frame()

2020-12-01 Thread James Almer

On 12/1/2020 5:19 PM, Anton Khirnov wrote:

This will be useful in the following commit.
---
  libavcodec/jpeglsdec.c|  2 +-
  libavcodec/mjpegdec.c | 71 +--
  libavcodec/mjpegdec.h |  8 ++--
  libavcodec/sp5xdec.c  | 28 ++
  tests/ref/fate/exif-image-jpg |  4 +-
  5 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 0b1e139048..e72f9f2315 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -551,7 +551,7 @@ AVCodec ff_jpegls_decoder = {
  .priv_data_size = sizeof(MJpegDecodeContext),
  .init   = ff_mjpeg_decode_init,
  .close  = ff_mjpeg_decode_end,
-.decode = ff_mjpeg_decode_frame,
+.receive_frame  = ff_mjpeg_receive_frame,
  .capabilities   = AV_CODEC_CAP_DR1,
  .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
  };
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 147dd819e5..96dfc3dc19 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -36,6 +36,7 @@
  #include "avcodec.h"
  #include "blockdsp.h"
  #include "copy_block.h"
+#include "decode.h"
  #include "hwconfig.h"
  #include "idctdsp.h"
  #include "internal.h"
@@ -163,6 +164,10 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
  s->picture_ptr = s->picture;
  }
  
+s->pkt = av_packet_alloc();

+if (!s->pkt)
+return AVERROR(ENOMEM);
+
  s->avctx = avctx;
  ff_blockdsp_init(>bdsp, avctx);
  ff_hpeldsp_init(>hdsp, avctx->flags);
@@ -2336,12 +2341,32 @@ static void reset_icc_profile(MJpegDecodeContext *s)
  s->iccnum  = 0;
  }
  
-int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,

-  AVPacket *avpkt)
+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)
  {
-AVFrame *frame = data;
-const uint8_t *buf = avpkt->data;
-int buf_size   = avpkt->size;
  MJpegDecodeContext *s = avctx->priv_data;
  const uint8_t *buf_end, *buf_ptr;
  const uint8_t *unescaped_buf_ptr;
@@ -2352,8 +2377,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
  int ret = 0;
  int is16bit;
  
-s->buf_size = buf_size;

-
  av_dict_free(>exif_metadata);
  av_freep(>stereo3d);
  s->adobe_transform = -1;
@@ -2361,8 +2384,12 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
  if (s->iccnum != 0)
  reset_icc_profile(s);
  
-buf_ptr = buf;

-buf_end = buf + buf_size;
+ret = mjpeg_get_packet(avctx);
+if (ret < 0)
+return ret;
+
+buf_ptr = s->pkt->data;
+buf_end = s->pkt->data + s->pkt->size;
  while (buf_ptr < buf_end) {
  /* find start next marker */
  start_code = ff_mjpeg_find_marker(s, _ptr, buf_end,
@@ -2374,7 +2401,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
  } else if (unescaped_buf_size > INT_MAX / 8) {
  av_log(avctx, AV_LOG_ERROR,
 "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
-   start_code, unescaped_buf_size, buf_size);
+   start_code, unescaped_buf_size, s->pkt->size);
  return AVERROR_INVALIDDATA;
  }
  av_log(avctx, AV_LOG_DEBUG, "marker=%x 
avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n",
@@ -2511,6 +2538,7 @@ eoi_parser:
  }
  if (avctx->skip_frame == AVDISCARD_ALL) {
  s->got_picture = 0;
+ret = AVERROR(EAGAIN);
  goto the_end_no_picture;
  }
  if (s->avctx->hwaccel) {
@@ -2522,9 +2550,10 @@ eoi_parser:
  }
  if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0)
  return ret;
-*got_frame = 1;
  s->got_picture = 0;
  
+frame->pkt_dts = s->pkt->dts;


You should set FF_CODEC_CAP_SETS_PKT_DTS for this (Not too important 
considering it's only checked for AVCodec->decode() decoders, but it 
could change in the future, so might as well keep the decoder ready for it).



+
  if (!s->lossless) {
  int qp = FFMAX3(s->qscale[0],
  s->qscale[1],
@@ -2533,7 +2562,7 @@ eoi_parser:
  AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
  

[FFmpeg-devel] [PATCH 7/9] mjpegdec: convert to receive_frame()

2020-12-01 Thread Anton Khirnov
This will be useful in the following commit.
---
 libavcodec/jpeglsdec.c|  2 +-
 libavcodec/mjpegdec.c | 71 +--
 libavcodec/mjpegdec.h |  8 ++--
 libavcodec/sp5xdec.c  | 28 ++
 tests/ref/fate/exif-image-jpg |  4 +-
 5 files changed, 72 insertions(+), 41 deletions(-)

diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 0b1e139048..e72f9f2315 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -551,7 +551,7 @@ AVCodec ff_jpegls_decoder = {
 .priv_data_size = sizeof(MJpegDecodeContext),
 .init   = ff_mjpeg_decode_init,
 .close  = ff_mjpeg_decode_end,
-.decode = ff_mjpeg_decode_frame,
+.receive_frame  = ff_mjpeg_receive_frame,
 .capabilities   = AV_CODEC_CAP_DR1,
 .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
 };
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 147dd819e5..96dfc3dc19 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -36,6 +36,7 @@
 #include "avcodec.h"
 #include "blockdsp.h"
 #include "copy_block.h"
+#include "decode.h"
 #include "hwconfig.h"
 #include "idctdsp.h"
 #include "internal.h"
@@ -163,6 +164,10 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
 s->picture_ptr = s->picture;
 }
 
+s->pkt = av_packet_alloc();
+if (!s->pkt)
+return AVERROR(ENOMEM);
+
 s->avctx = avctx;
 ff_blockdsp_init(>bdsp, avctx);
 ff_hpeldsp_init(>hdsp, avctx->flags);
@@ -2336,12 +2341,32 @@ static void reset_icc_profile(MJpegDecodeContext *s)
 s->iccnum  = 0;
 }
 
-int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-  AVPacket *avpkt)
+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)
 {
-AVFrame *frame = data;
-const uint8_t *buf = avpkt->data;
-int buf_size   = avpkt->size;
 MJpegDecodeContext *s = avctx->priv_data;
 const uint8_t *buf_end, *buf_ptr;
 const uint8_t *unescaped_buf_ptr;
@@ -2352,8 +2377,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
 int ret = 0;
 int is16bit;
 
-s->buf_size = buf_size;
-
 av_dict_free(>exif_metadata);
 av_freep(>stereo3d);
 s->adobe_transform = -1;
@@ -2361,8 +2384,12 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
 if (s->iccnum != 0)
 reset_icc_profile(s);
 
-buf_ptr = buf;
-buf_end = buf + buf_size;
+ret = mjpeg_get_packet(avctx);
+if (ret < 0)
+return ret;
+
+buf_ptr = s->pkt->data;
+buf_end = s->pkt->data + s->pkt->size;
 while (buf_ptr < buf_end) {
 /* find start next marker */
 start_code = ff_mjpeg_find_marker(s, _ptr, buf_end,
@@ -2374,7 +2401,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void 
*data, int *got_frame,
 } else if (unescaped_buf_size > INT_MAX / 8) {
 av_log(avctx, AV_LOG_ERROR,
"MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
-   start_code, unescaped_buf_size, buf_size);
+   start_code, unescaped_buf_size, s->pkt->size);
 return AVERROR_INVALIDDATA;
 }
 av_log(avctx, AV_LOG_DEBUG, "marker=%x 
avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n",
@@ -2511,6 +2538,7 @@ eoi_parser:
 }
 if (avctx->skip_frame == AVDISCARD_ALL) {
 s->got_picture = 0;
+ret = AVERROR(EAGAIN);
 goto the_end_no_picture;
 }
 if (s->avctx->hwaccel) {
@@ -2522,9 +2550,10 @@ eoi_parser:
 }
 if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0)
 return ret;
-*got_frame = 1;
 s->got_picture = 0;
 
+frame->pkt_dts = s->pkt->dts;
+
 if (!s->lossless) {
 int qp = FFMAX3(s->qscale[0],
 s->qscale[1],
@@ -2533,7 +2562,7 @@ eoi_parser:
 AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
 if (qp_table_buf) {
 memset(qp_table_buf->data, qp, qpw);
-av_frame_set_qp_table(data, qp_table_buf, 0, 
FF_QSCALE_TYPE_MPEG1);
+av_frame_set_qp_table(frame, qp_table_buf, 0, 
FF_QSCALE_TYPE_MPEG1);
 }
 
 if(avctx->debug &