avcodec/cavsdec: Propagate error codes inside decode_mb_i()
[ffmpeg.git] / libavcodec / mjpegenc_common.c
index 8ec3df9..31868c9 100644 (file)
@@ -36,7 +36,7 @@
 #include "mjpegenc_huffman.h"
 #include "mjpeg.h"
 
-av_cold void init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len)
+av_cold void ff_init_uni_ac_vlc(const uint8_t huff_size_ac[256], uint8_t *uni_ac_vlc_len)
 {
     int i;
 
@@ -91,13 +91,17 @@ static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
 {
     int i, j, size;
     uint8_t *ptr;
-    MpegEncContext *s = avctx->priv_data;
+    MpegEncContext *s = NULL;
+
+    /* Since avctx->priv_data will point to LJpegEncContext in this case */
+    if (avctx->codec_id != AV_CODEC_ID_LJPEG)
+        s = avctx->priv_data;
 
     if (avctx->codec_id != AV_CODEC_ID_LJPEG) {
         int matrix_count = 1 + !!memcmp(luma_intra_matrix,
                                         chroma_intra_matrix,
                                         sizeof(luma_intra_matrix[0]) * 64);
-    if (s->force_duplicated_matrix)
+    if (s && s->force_duplicated_matrix)
         matrix_count = 2;
     /* quant matrixes */
     put_marker(p, DQT);
@@ -134,7 +138,7 @@ static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,
 
     // Only MJPEG can have a variable Huffman variable. All other
     // formats use the default Huffman table.
-    if (s->out_format == FMT_MJPEG && s->huffman == HUFFMAN_TABLE_OPTIMAL) {
+    if (s && s->huffman == HUFFMAN_TABLE_OPTIMAL) {
         size += put_huffman_table(p, 0, 0, s->mjpeg_ctx->bits_dc_luminance,
                                   s->mjpeg_ctx->val_dc_luminance);
         size += put_huffman_table(p, 0, 1, s->mjpeg_ctx->bits_dc_chrominance,
@@ -355,6 +359,54 @@ end:
     }
 }
 
+/**
+ * Encodes and outputs the entire frame in the JPEG format.
+ *
+ * @param s The MpegEncContext.
+ */
+void ff_mjpeg_encode_picture_frame(MpegEncContext *s)
+{
+    int i, nbits, code, table_id;
+    MJpegContext *m = s->mjpeg_ctx;
+    uint8_t *huff_size[4] = {m->huff_size_dc_luminance,
+                             m->huff_size_dc_chrominance,
+                             m->huff_size_ac_luminance,
+                             m->huff_size_ac_chrominance};
+    uint16_t *huff_code[4] = {m->huff_code_dc_luminance,
+                              m->huff_code_dc_chrominance,
+                              m->huff_code_ac_luminance,
+                              m->huff_code_ac_chrominance};
+    size_t total_bits = 0;
+    size_t bytes_needed;
+
+    s->header_bits = get_bits_diff(s);
+    // Estimate the total size first
+    for (i = 0; i < m->huff_ncode; i++) {
+        table_id = m->huff_buffer[i].table_id;
+        code = m->huff_buffer[i].code;
+        nbits = code & 0xf;
+
+        total_bits += huff_size[table_id][code] + nbits;
+    }
+
+    bytes_needed = (total_bits + 7) / 8;
+    ff_mpv_reallocate_putbitbuffer(s, bytes_needed, bytes_needed);
+
+    for (i = 0; i < m->huff_ncode; i++) {
+        table_id = m->huff_buffer[i].table_id;
+        code = m->huff_buffer[i].code;
+        nbits = code & 0xf;
+
+        put_bits(&s->pb, huff_size[table_id][code], huff_code[table_id][code]);
+        if (nbits != 0) {
+            put_sbits(&s->pb, nbits, m->huff_buffer[i].mant);
+        }
+    }
+
+    m->huff_ncode = 0;
+    s->i_tex_bits = get_bits_diff(s);
+}
+
 void ff_mjpeg_escape_FF(PutBitContext *pb, int start)
 {
     int size;
@@ -424,7 +476,7 @@ void ff_mjpeg_escape_FF(PutBitContext *pb, int start)
  */
 static void ff_mjpeg_build_optimal_huffman(MJpegContext *m)
 {
-    int i, ret, table_id, code;
+    int i, table_id, code;
 
     MJpegEncHuffmanContext dc_luminance_ctx;
     MJpegEncHuffmanContext dc_chrominance_ctx;
@@ -444,22 +496,18 @@ static void ff_mjpeg_build_optimal_huffman(MJpegContext *m)
         ff_mjpeg_encode_huffman_increment(ctx[table_id], code);
     }
 
-    ret = ff_mjpeg_encode_huffman_close(&dc_luminance_ctx,
-                                        m->bits_dc_luminance,
-                                        m->val_dc_luminance, 12);
-    av_assert0(!ret);
-    ret = ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx,
-                                        m->bits_dc_chrominance,
-                                        m->val_dc_chrominance, 12);
-    av_assert0(!ret);
-    ret = ff_mjpeg_encode_huffman_close(&ac_luminance_ctx,
-                                        m->bits_ac_luminance,
-                                        m->val_ac_luminance, 256);
-    av_assert0(!ret);
-    ret = ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx,
-                                        m->bits_ac_chrominance,
-                                        m->val_ac_chrominance, 256);
-    av_assert0(!ret);
+    ff_mjpeg_encode_huffman_close(&dc_luminance_ctx,
+                                  m->bits_dc_luminance,
+                                  m->val_dc_luminance, 12);
+    ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx,
+                                  m->bits_dc_chrominance,
+                                  m->val_dc_chrominance, 12);
+    ff_mjpeg_encode_huffman_close(&ac_luminance_ctx,
+                                  m->bits_ac_luminance,
+                                  m->val_ac_luminance, 256);
+    ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx,
+                                  m->bits_ac_chrominance,
+                                  m->val_ac_chrominance, 256);
 
     ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance,
                                  m->huff_code_dc_luminance,
@@ -480,7 +528,8 @@ static void ff_mjpeg_build_optimal_huffman(MJpegContext *m)
 }
 
 /**
- * Writes the complete JPEG frame.
+ * Writes the complete JPEG frame when optimal huffman tables are enabled,
+ * otherwise writes the stuffing.
  *
  * Header + values + stuffing.
  *
@@ -497,28 +546,21 @@ int ff_mjpeg_encode_stuffing(MpegEncContext *s)
 
     m = s->mjpeg_ctx;
 
-    if (m->error)
-        return m->error;
-
     if (s->huffman == HUFFMAN_TABLE_OPTIMAL) {
         ff_mjpeg_build_optimal_huffman(m);
 
         // Replace the VLCs with the optimal ones.
         // The default ones may be used for trellis during quantization.
-        init_uni_ac_vlc(m->huff_size_ac_luminance,   m->uni_ac_vlc_len);
-        init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len);
+        ff_init_uni_ac_vlc(m->huff_size_ac_luminance,   m->uni_ac_vlc_len);
+        ff_init_uni_ac_vlc(m->huff_size_ac_chrominance, m->uni_chroma_ac_vlc_len);
         s->intra_ac_vlc_length      =
         s->intra_ac_vlc_last_length = m->uni_ac_vlc_len;
         s->intra_chroma_ac_vlc_length      =
         s->intra_chroma_ac_vlc_last_length = m->uni_chroma_ac_vlc_len;
-    }
 
-    ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
-                                   s->pred, s->intra_matrix, s->chroma_intra_matrix);
-    ff_mjpeg_encode_picture_frame(s);
-    if (m->error < 0) {
-        ret = m->error;
-        return ret;
+        ff_mjpeg_encode_picture_header(s->avctx, &s->pb, &s->intra_scantable,
+                                       s->pred, s->intra_matrix, s->chroma_intra_matrix);
+        ff_mjpeg_encode_picture_frame(s);
     }
 
     ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100,