Message ID | 20201201201949.18834-7-anton@khirnov.net |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/9] img2dec: export avg_frame_rate | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
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(&s->bdsp, avctx); > ff_hpeldsp_init(&s->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(&s->exif_metadata); > av_freep(&s->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, &buf_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); > 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 & FF_DEBUG_QP) > @@ -2774,7 +2803,7 @@ the_end: > } > > if (s->stereo3d) { > - AVStereo3D *stereo = av_stereo3d_create_side_data(data); > + AVStereo3D *stereo = av_stereo3d_create_side_data(frame); > if (stereo) { > stereo->type = s->stereo3d->type; > stereo->flags = s->stereo3d->flags; > @@ -2792,7 +2821,7 @@ the_end: > for (i = 0; i < s->iccnum; i++) > total_size += s->iccdatalens[i]; > > - sd = av_frame_new_side_data(data, AV_FRAME_DATA_ICC_PROFILE, total_size); > + sd = av_frame_new_side_data(frame, AV_FRAME_DATA_ICC_PROFILE, total_size); > if (!sd) { > av_log(s->avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); > return AVERROR(ENOMEM); > @@ -2805,14 +2834,16 @@ the_end: > } > } > > - av_dict_copy(&((AVFrame *) data)->metadata, s->exif_metadata, 0); > + av_dict_copy(&frame->metadata, s->exif_metadata, 0); > av_dict_free(&s->exif_metadata); > > + ret = 0; > + > the_end_no_picture: > av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n", > buf_end - buf_ptr); > -// return buf_end - buf_ptr; > - return buf_ptr - buf; > + > + return ret; > } > > av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) > @@ -2830,6 +2861,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) > } else if (s->picture_ptr) > av_frame_unref(s->picture_ptr); > > + av_packet_free(&s->pkt); > + > av_freep(&s->buffer); > av_freep(&s->stereo3d); > av_freep(&s->ljpeg_buffer); > @@ -2882,7 +2915,7 @@ AVCodec ff_mjpeg_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, > .flush = decode_flush, > .capabilities = AV_CODEC_CAP_DR1, > .max_lowres = 3, > @@ -2910,7 +2943,7 @@ AVCodec ff_thp_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, > .flush = decode_flush, > .capabilities = AV_CODEC_CAP_DR1, > .max_lowres = 3, > diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h > index 9d1666bebd..66fb0ddcba 100644 > --- a/libavcodec/mjpegdec.h > +++ b/libavcodec/mjpegdec.h > @@ -49,6 +49,8 @@ typedef struct MJpegDecodeContext { > GetBitContext gb; > int buf_size; > > + AVPacket *pkt; > + > int start_code; /* current start code */ > int buffer_size; > uint8_t *buffer; > @@ -156,9 +158,7 @@ typedef struct MJpegDecodeContext { > > int ff_mjpeg_decode_init(AVCodecContext *avctx); > int ff_mjpeg_decode_end(AVCodecContext *avctx); > -int ff_mjpeg_decode_frame(AVCodecContext *avctx, > - void *data, int *got_frame, > - AVPacket *avpkt); > +int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame); > int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); > int ff_mjpeg_decode_dht(MJpegDecodeContext *s); > int ff_mjpeg_decode_sof(MJpegDecodeContext *s); > @@ -169,4 +169,6 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, > const uint8_t **buf_ptr, const uint8_t *buf_end, > const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); > > +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt); > + > #endif /* AVCODEC_MJPEGDEC_H */ > diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c > index 815f9ad50e..7be6cf37a9 100644 > --- a/libavcodec/sp5xdec.c > +++ b/libavcodec/sp5xdec.c > @@ -30,14 +30,11 @@ > #include "mjpegdec.h" > #include "sp5x.h" > > - > -static int sp5x_decode_frame(AVCodecContext *avctx, > - void *data, int *got_frame, > - AVPacket *avpkt) > +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) > { > const uint8_t *buf = avpkt->data; > int buf_size = avpkt->size; > - AVPacket avpkt_recoded; > + AVBufferRef *buf_recoded; > const int qscale = 5; > uint8_t *recoded; > int i = 0, j = 0; > @@ -45,9 +42,10 @@ static int sp5x_decode_frame(AVCodecContext *avctx, > if (!avctx->width || !avctx->height) > return -1; > > - recoded = av_mallocz(buf_size + 1024); > - if (!recoded) > + buf_recoded = av_buffer_allocz(buf_size + 1024); > + if (!buf_recoded) > return -1; > + recoded = buf_recoded->data; > > /* SOI */ > recoded[j++] = 0xFF; > @@ -84,14 +82,12 @@ static int sp5x_decode_frame(AVCodecContext *avctx, > recoded[j++] = 0xFF; > recoded[j++] = 0xD9; > > - av_init_packet(&avpkt_recoded); > - avpkt_recoded.data = recoded; > - avpkt_recoded.size = j; > - i = ff_mjpeg_decode_frame(avctx, data, got_frame, &avpkt_recoded); > - > - av_free(recoded); > + av_buffer_unref(&avpkt->buf); > + avpkt->buf = buf_recoded; > + avpkt->data = recoded; > + avpkt->size = j; > > - return i < 0 ? i : avpkt->size; > + return 0; > } > > #if CONFIG_SP5X_DECODER > @@ -103,7 +99,7 @@ AVCodec ff_sp5x_decoder = { > .priv_data_size = sizeof(MJpegDecodeContext), > .init = ff_mjpeg_decode_init, > .close = ff_mjpeg_decode_end, > - .decode = sp5x_decode_frame, > + .receive_frame = ff_mjpeg_receive_frame, > .capabilities = AV_CODEC_CAP_DR1, > .max_lowres = 3, > .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, > @@ -118,7 +114,7 @@ AVCodec ff_amv_decoder = { > .priv_data_size = sizeof(MJpegDecodeContext), > .init = ff_mjpeg_decode_init, > .close = ff_mjpeg_decode_end, > - .decode = sp5x_decode_frame, > + .receive_frame = ff_mjpeg_receive_frame, > .max_lowres = 3, > .capabilities = AV_CODEC_CAP_DR1, > .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, > diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg > index eb18dede21..1563f3ef6a 100644 > --- a/tests/ref/fate/exif-image-jpg > +++ b/tests/ref/fate/exif-image-jpg > @@ -6,8 +6,8 @@ pkt_pts=0 > pkt_pts_time=0.000000 > pkt_dts=0 > pkt_dts_time=0.000000 > -best_effort_timestamp=0 > -best_effort_timestamp_time=0.000000 > +best_effort_timestamp=N/A > +best_effort_timestamp_time=N/A The decode API doesn't set this for AVCodec->receive_frame() implementations, only for AVCodec->decode() ones. You could work around this by setting out_frame->best_effort_timestamp to in_pkt->pts in this decoder. Should work as is since this decoder is not a AV_CODEC_PROP_REORDER one. It's what the libdav1d wrapper does. Otherwise, guess_correct_pts() in decode.c could be called for AVCodec->receive_frame() decoders, too, or a similar solution, and ensure it will be set for all such future decoders. > pkt_duration=1 > pkt_duration_time=0.040000 > pkt_pos=N/A >
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(&s->bdsp, avctx); ff_hpeldsp_init(&s->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(&s->exif_metadata); av_freep(&s->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, &buf_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 & FF_DEBUG_QP) @@ -2774,7 +2803,7 @@ the_end: } if (s->stereo3d) { - AVStereo3D *stereo = av_stereo3d_create_side_data(data); + AVStereo3D *stereo = av_stereo3d_create_side_data(frame); if (stereo) { stereo->type = s->stereo3d->type; stereo->flags = s->stereo3d->flags; @@ -2792,7 +2821,7 @@ the_end: for (i = 0; i < s->iccnum; i++) total_size += s->iccdatalens[i]; - sd = av_frame_new_side_data(data, AV_FRAME_DATA_ICC_PROFILE, total_size); + sd = av_frame_new_side_data(frame, AV_FRAME_DATA_ICC_PROFILE, total_size); if (!sd) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate frame side data\n"); return AVERROR(ENOMEM); @@ -2805,14 +2834,16 @@ the_end: } } - av_dict_copy(&((AVFrame *) data)->metadata, s->exif_metadata, 0); + av_dict_copy(&frame->metadata, s->exif_metadata, 0); av_dict_free(&s->exif_metadata); + ret = 0; + the_end_no_picture: av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n", buf_end - buf_ptr); -// return buf_end - buf_ptr; - return buf_ptr - buf; + + return ret; } av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) @@ -2830,6 +2861,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) } else if (s->picture_ptr) av_frame_unref(s->picture_ptr); + av_packet_free(&s->pkt); + av_freep(&s->buffer); av_freep(&s->stereo3d); av_freep(&s->ljpeg_buffer); @@ -2882,7 +2915,7 @@ AVCodec ff_mjpeg_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, .flush = decode_flush, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, @@ -2910,7 +2943,7 @@ AVCodec ff_thp_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, .flush = decode_flush, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 9d1666bebd..66fb0ddcba 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -49,6 +49,8 @@ typedef struct MJpegDecodeContext { GetBitContext gb; int buf_size; + AVPacket *pkt; + int start_code; /* current start code */ int buffer_size; uint8_t *buffer; @@ -156,9 +158,7 @@ typedef struct MJpegDecodeContext { int ff_mjpeg_decode_init(AVCodecContext *avctx); int ff_mjpeg_decode_end(AVCodecContext *avctx); -int ff_mjpeg_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt); +int ff_mjpeg_receive_frame(AVCodecContext *avctx, AVFrame *frame); int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); int ff_mjpeg_decode_dht(MJpegDecodeContext *s); int ff_mjpeg_decode_sof(MJpegDecodeContext *s); @@ -169,4 +169,6 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt); + #endif /* AVCODEC_MJPEGDEC_H */ diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c index 815f9ad50e..7be6cf37a9 100644 --- a/libavcodec/sp5xdec.c +++ b/libavcodec/sp5xdec.c @@ -30,14 +30,11 @@ #include "mjpegdec.h" #include "sp5x.h" - -static int sp5x_decode_frame(AVCodecContext *avctx, - void *data, int *got_frame, - AVPacket *avpkt) +int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - AVPacket avpkt_recoded; + AVBufferRef *buf_recoded; const int qscale = 5; uint8_t *recoded; int i = 0, j = 0; @@ -45,9 +42,10 @@ static int sp5x_decode_frame(AVCodecContext *avctx, if (!avctx->width || !avctx->height) return -1; - recoded = av_mallocz(buf_size + 1024); - if (!recoded) + buf_recoded = av_buffer_allocz(buf_size + 1024); + if (!buf_recoded) return -1; + recoded = buf_recoded->data; /* SOI */ recoded[j++] = 0xFF; @@ -84,14 +82,12 @@ static int sp5x_decode_frame(AVCodecContext *avctx, recoded[j++] = 0xFF; recoded[j++] = 0xD9; - av_init_packet(&avpkt_recoded); - avpkt_recoded.data = recoded; - avpkt_recoded.size = j; - i = ff_mjpeg_decode_frame(avctx, data, got_frame, &avpkt_recoded); - - av_free(recoded); + av_buffer_unref(&avpkt->buf); + avpkt->buf = buf_recoded; + avpkt->data = recoded; + avpkt->size = j; - return i < 0 ? i : avpkt->size; + return 0; } #if CONFIG_SP5X_DECODER @@ -103,7 +99,7 @@ AVCodec ff_sp5x_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = sp5x_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .capabilities = AV_CODEC_CAP_DR1, .max_lowres = 3, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, @@ -118,7 +114,7 @@ AVCodec ff_amv_decoder = { .priv_data_size = sizeof(MJpegDecodeContext), .init = ff_mjpeg_decode_init, .close = ff_mjpeg_decode_end, - .decode = sp5x_decode_frame, + .receive_frame = ff_mjpeg_receive_frame, .max_lowres = 3, .capabilities = AV_CODEC_CAP_DR1, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, diff --git a/tests/ref/fate/exif-image-jpg b/tests/ref/fate/exif-image-jpg index eb18dede21..1563f3ef6a 100644 --- a/tests/ref/fate/exif-image-jpg +++ b/tests/ref/fate/exif-image-jpg @@ -6,8 +6,8 @@ pkt_pts=0 pkt_pts_time=0.000000 pkt_dts=0 pkt_dts_time=0.000000 -best_effort_timestamp=0 -best_effort_timestamp_time=0.000000 +best_effort_timestamp=N/A +best_effort_timestamp_time=N/A pkt_duration=1 pkt_duration_time=0.040000 pkt_pos=N/A