[FFmpeg-cvslog] avcodec/mjpegenc: Fix files with slices > 1, but threads == 1

Andreas Rheinhardt git at videolan.org
Fri Apr 1 19:18:08 EEST 2022


ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinhardt at outlook.com> | Sun Jan 30 04:07:51 2022 +0100| [9b3279b20198a46aae08c29c3b4c4ce75ff637ff] | committer: Andreas Rheinhardt

avcodec/mjpegenc: Fix files with slices > 1, but threads == 1

In the aforementioned case mpegvideo_enc.c calls
ff_mjpeg_encode_stuffing() at the end of every line which
pads the output to byte-alignment and escapes it;
yet it does not write the restart-markers (and also not
the DRI marker when writing the header) and so the output files
are broken.

Fix this by writing these markers depending upon the number of
slices and not the number of threads in use; this also makes
the output of the encoder reproducible given a slice count
and is therefore important if encoder tests that actually use
-threads auto are added in the future.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9b3279b20198a46aae08c29c3b4c4ce75ff637ff
---

 libavcodec/ljpegenc.c        |  2 +-
 libavcodec/mjpegenc.c        | 12 ++++++++----
 libavcodec/mjpegenc_common.c | 10 ++++++----
 libavcodec/mjpegenc_common.h |  3 ++-
 4 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index fad19cbb76..1af4475b75 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -239,7 +239,7 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     init_put_bits(&pb, pkt->data, pkt->size);
 
     ff_mjpeg_encode_picture_header(avctx, &pb, NULL, &s->scantable,
-                                   s->pred, s->matrix, s->matrix);
+                                   s->pred, s->matrix, s->matrix, 0);
 
     header_bits = put_bits_count(&pb);
 
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 58b0f2bb37..6ea113afb2 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -82,7 +82,8 @@ static void mjpeg_encode_picture_header(MpegEncContext *s)
 {
     ff_mjpeg_encode_picture_header(s->avctx, &s->pb, s->mjpeg_ctx,
                                    &s->intra_scantable, 0,
-                                   s->intra_matrix, s->chroma_intra_matrix);
+                                   s->intra_matrix, s->chroma_intra_matrix,
+                                   s->slice_context_count > 1);
 
     s->esc_pos = put_bytes_count(&s->pb, 0);
     for (int i = 1; i < s->slice_context_count; i++)
@@ -251,7 +252,7 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
 
     ff_mjpeg_escape_FF(pbc, s->esc_pos);
 
-    if ((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height - 1)
+    if (s->slice_context_count > 1 && mb_y < s->mb_height - 1)
         put_marker(pbc, RST0 + (mb_y&7));
     s->esc_pos = put_bytes_count(pbc, 0);
 
@@ -293,11 +294,14 @@ static int alloc_huffman(MpegEncContext *s)
 av_cold int ff_mjpeg_encode_init(MpegEncContext *s)
 {
     MJpegContext *const m = &((MJPEGEncContext*)s)->mjpeg;
-    int ret;
+    int ret, use_slices;
 
     s->mjpeg_ctx = m;
+    use_slices = s->avctx->slices > 0 ? s->avctx->slices > 1 :
+                 (s->avctx->active_thread_type & FF_THREAD_SLICE) &&
+                 s->avctx->thread_count > 1;
 
-    if (s->codec_id == AV_CODEC_ID_AMV || (s->avctx->active_thread_type & FF_THREAD_SLICE))
+    if (s->codec_id == AV_CODEC_ID_AMV || use_slices)
         m->huffman = HUFFMAN_TABLE_DEFAULT;
 
     if (s->mpv_flags & FF_MPV_FLAG_QP_RD) {
diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c
index 7b82644763..4143a372bb 100644
--- a/libavcodec/mjpegenc_common.c
+++ b/libavcodec/mjpegenc_common.c
@@ -61,7 +61,7 @@ static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
                               ScanTable *intra_scantable,
                               uint16_t luma_intra_matrix[64],
                               uint16_t chroma_intra_matrix[64],
-                              int hsample[3])
+                              int hsample[3], int use_slices)
 {
     int i, j, size;
     uint8_t *ptr;
@@ -92,7 +92,7 @@ static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
         }
     }
 
-    if(avctx->active_thread_type & FF_THREAD_SLICE){
+    if (use_slices) {
         put_marker(p, DRI);
         put_bits(p, 16, 4);
         put_bits(p, 16, (avctx->width-1)/(8*hsample[0]) + 1);
@@ -217,7 +217,8 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
                                     MJpegContext *m,
                                     ScanTable *intra_scantable, int pred,
                                     uint16_t luma_intra_matrix[64],
-                                    uint16_t chroma_intra_matrix[64])
+                                    uint16_t chroma_intra_matrix[64],
+                                    int use_slices)
 {
     const int lossless = !m;
     int hsample[4], vsample[4];
@@ -237,7 +238,8 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
     jpeg_put_comments(avctx, pb);
 
     jpeg_table_header(avctx, pb, m, intra_scantable,
-                      luma_intra_matrix, chroma_intra_matrix, hsample);
+                      luma_intra_matrix, chroma_intra_matrix, hsample,
+                      use_slices);
 
     switch (avctx->codec_id) {
     case AV_CODEC_ID_MJPEG:  put_marker(pb, SOF0 ); break;
diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h
index ac753bf153..ba7c4f93fa 100644
--- a/libavcodec/mjpegenc_common.h
+++ b/libavcodec/mjpegenc_common.h
@@ -33,7 +33,8 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb,
                                     struct MJpegContext *m,
                                     ScanTable *intra_scantable, int pred,
                                     uint16_t luma_intra_matrix[64],
-                                    uint16_t chroma_intra_matrix[64]);
+                                    uint16_t chroma_intra_matrix[64],
+                                    int use_slices);
 void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits);
 void ff_mjpeg_escape_FF(PutBitContext *pb, int start);
 void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code,



More information about the ffmpeg-cvslog mailing list