LCOV - code coverage report
Current view: top level - libavcodec - utvideoenc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 252 305 82.6 %
Date: 2017-12-15 18:13:28 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Ut Video encoder
       3             :  * Copyright (c) 2012 Jan Ekström
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Ut Video encoder
      25             :  */
      26             : 
      27             : #include "libavutil/imgutils.h"
      28             : #include "libavutil/intreadwrite.h"
      29             : #include "libavutil/opt.h"
      30             : 
      31             : #include "avcodec.h"
      32             : #include "internal.h"
      33             : #include "bswapdsp.h"
      34             : #include "bytestream.h"
      35             : #include "put_bits.h"
      36             : #include "mathops.h"
      37             : #include "utvideo.h"
      38             : #include "huffman.h"
      39             : 
      40             : /* Compare huffentry symbols */
      41     3144318 : static int huff_cmp_sym(const void *a, const void *b)
      42             : {
      43     3144318 :     const HuffEntry *aa = a, *bb = b;
      44     3144318 :     return aa->sym - bb->sym;
      45             : }
      46             : 
      47         135 : static av_cold int utvideo_encode_close(AVCodecContext *avctx)
      48             : {
      49         135 :     UtvideoContext *c = avctx->priv_data;
      50             :     int i;
      51             : 
      52         135 :     av_freep(&c->slice_bits);
      53         675 :     for (i = 0; i < 4; i++)
      54         540 :         av_freep(&c->slice_buffer[i]);
      55             : 
      56         135 :     return 0;
      57             : }
      58             : 
      59         135 : static av_cold int utvideo_encode_init(AVCodecContext *avctx)
      60             : {
      61         135 :     UtvideoContext *c = avctx->priv_data;
      62             :     int i, subsampled_height;
      63             :     uint32_t original_format;
      64             : 
      65         135 :     c->avctx           = avctx;
      66         135 :     c->frame_info_size = 4;
      67         135 :     c->slice_stride    = FFALIGN(avctx->width, 32);
      68             : 
      69         135 :     switch (avctx->pix_fmt) {
      70          27 :     case AV_PIX_FMT_RGB24:
      71          27 :         c->planes        = 3;
      72          27 :         avctx->codec_tag = MKTAG('U', 'L', 'R', 'G');
      73          27 :         original_format  = UTVIDEO_RGB;
      74          27 :         break;
      75          27 :     case AV_PIX_FMT_RGBA:
      76          27 :         c->planes        = 4;
      77          27 :         avctx->codec_tag = MKTAG('U', 'L', 'R', 'A');
      78          27 :         original_format  = UTVIDEO_RGBA;
      79          27 :         avctx->bits_per_coded_sample = 32;
      80          27 :         break;
      81          27 :     case AV_PIX_FMT_YUV420P:
      82          27 :         if (avctx->width & 1 || avctx->height & 1) {
      83           0 :             av_log(avctx, AV_LOG_ERROR,
      84             :                    "4:2:0 video requires even width and height.\n");
      85           0 :             return AVERROR_INVALIDDATA;
      86             :         }
      87          27 :         c->planes        = 3;
      88          27 :         if (avctx->colorspace == AVCOL_SPC_BT709)
      89           0 :             avctx->codec_tag = MKTAG('U', 'L', 'H', '0');
      90             :         else
      91          27 :             avctx->codec_tag = MKTAG('U', 'L', 'Y', '0');
      92          27 :         original_format  = UTVIDEO_420;
      93          27 :         break;
      94          27 :     case AV_PIX_FMT_YUV422P:
      95          27 :         if (avctx->width & 1) {
      96           0 :             av_log(avctx, AV_LOG_ERROR,
      97             :                    "4:2:2 video requires even width.\n");
      98           0 :             return AVERROR_INVALIDDATA;
      99             :         }
     100          27 :         c->planes        = 3;
     101          27 :         if (avctx->colorspace == AVCOL_SPC_BT709)
     102           0 :             avctx->codec_tag = MKTAG('U', 'L', 'H', '2');
     103             :         else
     104          27 :             avctx->codec_tag = MKTAG('U', 'L', 'Y', '2');
     105          27 :         original_format  = UTVIDEO_422;
     106          27 :         break;
     107          27 :     case AV_PIX_FMT_YUV444P:
     108          27 :         c->planes        = 3;
     109          27 :         if (avctx->colorspace == AVCOL_SPC_BT709)
     110           0 :             avctx->codec_tag = MKTAG('U', 'L', 'H', '4');
     111             :         else
     112          27 :             avctx->codec_tag = MKTAG('U', 'L', 'Y', '4');
     113          27 :         original_format  = UTVIDEO_444;
     114          27 :         break;
     115           0 :     default:
     116           0 :         av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
     117           0 :                avctx->pix_fmt);
     118           0 :         return AVERROR_INVALIDDATA;
     119             :     }
     120             : 
     121         135 :     ff_bswapdsp_init(&c->bdsp);
     122         135 :     ff_llvidencdsp_init(&c->llvidencdsp);
     123             : 
     124             : #if FF_API_PRIVATE_OPT
     125             : FF_DISABLE_DEPRECATION_WARNINGS
     126             :     /* Check the prediction method, and error out if unsupported */
     127         135 :     if (avctx->prediction_method < 0 || avctx->prediction_method > 4) {
     128           0 :         av_log(avctx, AV_LOG_WARNING,
     129             :                "Prediction method %d is not supported in Ut Video.\n",
     130             :                avctx->prediction_method);
     131           0 :         return AVERROR_OPTION_NOT_FOUND;
     132             :     }
     133             : 
     134         135 :     if (avctx->prediction_method == FF_PRED_PLANE) {
     135           0 :         av_log(avctx, AV_LOG_ERROR,
     136             :                "Plane prediction is not supported in Ut Video.\n");
     137           0 :         return AVERROR_OPTION_NOT_FOUND;
     138             :     }
     139             : 
     140             :     /* Convert from libavcodec prediction type to Ut Video's */
     141         135 :     if (avctx->prediction_method)
     142           0 :         c->frame_pred = ff_ut_pred_order[avctx->prediction_method];
     143             : FF_ENABLE_DEPRECATION_WARNINGS
     144             : #endif
     145             : 
     146         135 :     if (c->frame_pred == PRED_GRADIENT) {
     147           0 :         av_log(avctx, AV_LOG_ERROR, "Gradient prediction is not supported.\n");
     148           0 :         return AVERROR_OPTION_NOT_FOUND;
     149             :     }
     150             : 
     151             :     /*
     152             :      * Check the asked slice count for obviously invalid
     153             :      * values (> 256 or negative).
     154             :      */
     155         135 :     if (avctx->slices > 256 || avctx->slices < 0) {
     156           0 :         av_log(avctx, AV_LOG_ERROR,
     157             :                "Slice count %d is not supported in Ut Video (theoretical range is 0-256).\n",
     158             :                avctx->slices);
     159           0 :         return AVERROR(EINVAL);
     160             :     }
     161             : 
     162             :     /* Check that the slice count is not larger than the subsampled height */
     163         135 :     subsampled_height = avctx->height >> av_pix_fmt_desc_get(avctx->pix_fmt)->log2_chroma_h;
     164         135 :     if (avctx->slices > subsampled_height) {
     165           0 :         av_log(avctx, AV_LOG_ERROR,
     166             :                "Slice count %d is larger than the subsampling-applied height %d.\n",
     167             :                avctx->slices, subsampled_height);
     168           0 :         return AVERROR(EINVAL);
     169             :     }
     170             : 
     171             :     /* extradata size is 4 * 32 bits */
     172         135 :     avctx->extradata_size = 16;
     173             : 
     174         135 :     avctx->extradata = av_mallocz(avctx->extradata_size +
     175             :                                   AV_INPUT_BUFFER_PADDING_SIZE);
     176             : 
     177         135 :     if (!avctx->extradata) {
     178           0 :         av_log(avctx, AV_LOG_ERROR, "Could not allocate extradata.\n");
     179           0 :         utvideo_encode_close(avctx);
     180           0 :         return AVERROR(ENOMEM);
     181             :     }
     182             : 
     183         567 :     for (i = 0; i < c->planes; i++) {
     184         432 :         c->slice_buffer[i] = av_malloc(c->slice_stride * (avctx->height + 2) +
     185             :                                        AV_INPUT_BUFFER_PADDING_SIZE);
     186         432 :         if (!c->slice_buffer[i]) {
     187           0 :             av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 1.\n");
     188           0 :             utvideo_encode_close(avctx);
     189           0 :             return AVERROR(ENOMEM);
     190             :         }
     191             :     }
     192             : 
     193             :     /*
     194             :      * Set the version of the encoder.
     195             :      * Last byte is "implementation ID", which is
     196             :      * obtained from the creator of the format.
     197             :      * Libavcodec has been assigned with the ID 0xF0.
     198             :      */
     199         135 :     AV_WB32(avctx->extradata, MKTAG(1, 0, 0, 0xF0));
     200             : 
     201             :     /*
     202             :      * Set the "original format"
     203             :      * Not used for anything during decoding.
     204             :      */
     205         135 :     AV_WL32(avctx->extradata + 4, original_format);
     206             : 
     207             :     /* Write 4 as the 'frame info size' */
     208         135 :     AV_WL32(avctx->extradata + 8, c->frame_info_size);
     209             : 
     210             :     /*
     211             :      * Set how many slices are going to be used.
     212             :      * By default uses multiple slices depending on the subsampled height.
     213             :      * This enables multithreading in the official decoder.
     214             :      */
     215         135 :     if (!avctx->slices) {
     216           0 :         c->slices = subsampled_height / 120;
     217             : 
     218           0 :         if (!c->slices)
     219           0 :             c->slices = 1;
     220           0 :         else if (c->slices > 256)
     221           0 :             c->slices = 256;
     222             :     } else {
     223         135 :         c->slices = avctx->slices;
     224             :     }
     225             : 
     226             :     /* Set compression mode */
     227         135 :     c->compression = COMP_HUFF;
     228             : 
     229             :     /*
     230             :      * Set the encoding flags:
     231             :      * - Slice count minus 1
     232             :      * - Interlaced encoding mode flag, set to zero for now.
     233             :      * - Compression mode (none/huff)
     234             :      * And write the flags.
     235             :      */
     236         135 :     c->flags  = (c->slices - 1) << 24;
     237         135 :     c->flags |= 0 << 11; // bit field to signal interlaced encoding mode
     238         135 :     c->flags |= c->compression;
     239             : 
     240         135 :     AV_WL32(avctx->extradata + 12, c->flags);
     241             : 
     242         135 :     return 0;
     243             : }
     244             : 
     245         300 : static void mangle_rgb_planes(uint8_t *dst[4], ptrdiff_t dst_stride,
     246             :                               uint8_t *src, int step, ptrdiff_t stride,
     247             :                               int width, int height)
     248             : {
     249             :     int i, j;
     250         300 :     int k = 2 * dst_stride;
     251             :     unsigned int g;
     252             : 
     253       86700 :     for (j = 0; j < height; j++) {
     254       86400 :         if (step == 3) {
     255    15249600 :             for (i = 0; i < width * step; i += step) {
     256    15206400 :                 g         = src[i + 1];
     257    15206400 :                 dst[0][k] = g;
     258    15206400 :                 g        += 0x80;
     259    15206400 :                 dst[1][k] = src[i + 2] - g;
     260    15206400 :                 dst[2][k] = src[i + 0] - g;
     261    15206400 :                 k++;
     262             :             }
     263             :         } else {
     264    15249600 :             for (i = 0; i < width * step; i += step) {
     265    15206400 :                 g         = src[i + 1];
     266    15206400 :                 dst[0][k] = g;
     267    15206400 :                 g        += 0x80;
     268    15206400 :                 dst[1][k] = src[i + 2] - g;
     269    15206400 :                 dst[2][k] = src[i + 0] - g;
     270    15206400 :                 dst[3][k] = src[i + 3];
     271    15206400 :                 k++;
     272             :             }
     273             :         }
     274       86400 :         k += dst_stride - width;
     275       86400 :         src += stride;
     276             :     }
     277         300 : }
     278             : 
     279             : /* Write data to a plane with left prediction */
     280         800 : static void left_predict(uint8_t *src, uint8_t *dst, ptrdiff_t stride,
     281             :                          int width, int height)
     282             : {
     283             :     int i, j;
     284             :     uint8_t prev;
     285             : 
     286         800 :     prev = 0x80; /* Set the initial value */
     287      216800 :     for (j = 0; j < height; j++) {
     288    68644800 :         for (i = 0; i < width; i++) {
     289    68428800 :             *dst++ = src[i] - prev;
     290    68428800 :             prev   = src[i];
     291             :         }
     292      216000 :         src += stride;
     293             :     }
     294         800 : }
     295             : 
     296             : #undef A
     297             : #undef B
     298             : 
     299             : /* Write data to a plane with median prediction */
     300         800 : static void median_predict(UtvideoContext *c, uint8_t *src, uint8_t *dst,
     301             :                            ptrdiff_t stride, int width, int height)
     302             : {
     303             :     int i, j;
     304             :     int A, B;
     305             :     uint8_t prev;
     306             : 
     307             :     /* First line uses left neighbour prediction */
     308         800 :     prev = 0x80; /* Set the initial value */
     309      247200 :     for (i = 0; i < width; i++) {
     310      246400 :         *dst++ = src[i] - prev;
     311      246400 :         prev   = src[i];
     312             :     }
     313             : 
     314         800 :     if (height == 1)
     315           0 :         return;
     316             : 
     317         800 :     src += stride;
     318             : 
     319             :     /*
     320             :      * Second line uses top prediction for the first sample,
     321             :      * and median for the rest.
     322             :      */
     323         800 :     A = B = 0;
     324             : 
     325             :     /* Rest of the coded part uses median prediction */
     326      216000 :     for (j = 1; j < height; j++) {
     327      215200 :         c->llvidencdsp.sub_median_pred(dst, src - stride, src, width, &A, &B);
     328      215200 :         dst += width;
     329      215200 :         src += stride;
     330             :     }
     331             : }
     332             : 
     333             : /* Count the usage of values in a plane */
     334        2400 : static void count_usage(uint8_t *src, int width,
     335             :                         int height, uint64_t *counts)
     336             : {
     337             :     int i, j;
     338             : 
     339      650400 :     for (j = 0; j < height; j++) {
     340   205934400 :         for (i = 0; i < width; i++) {
     341   205286400 :             counts[src[i]]++;
     342             :         }
     343      648000 :         src += width;
     344             :     }
     345        2400 : }
     346             : 
     347             : /* Calculate the actual huffman codes from the code lengths */
     348        2350 : static void calculate_codes(HuffEntry *he)
     349             : {
     350             :     int last, i;
     351             :     uint32_t code;
     352             : 
     353        2350 :     qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len);
     354             : 
     355        2350 :     last = 255;
     356       91889 :     while (he[last].len == 255 && last)
     357       87189 :         last--;
     358             : 
     359        2350 :     code = 1;
     360      516761 :     for (i = last; i >= 0; i--) {
     361      514411 :         he[i].code  = code >> (32 - he[i].len);
     362      514411 :         code       += 0x80000000u >> (he[i].len - 1);
     363             :     }
     364             : 
     365        2350 :     qsort(he, 256, sizeof(*he), huff_cmp_sym);
     366        2350 : }
     367             : 
     368             : /* Write huffman bit codes to a memory block */
     369        2350 : static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size,
     370             :                             int width, int height, HuffEntry *he)
     371             : {
     372             :     PutBitContext pb;
     373             :     int i, j;
     374             :     int count;
     375             : 
     376        2350 :     init_put_bits(&pb, dst, dst_size);
     377             : 
     378             :     /* Write the codes */
     379      635950 :     for (j = 0; j < height; j++) {
     380   200851200 :         for (i = 0; i < width; i++)
     381   200217600 :             put_bits(&pb, he[src[i]].len, he[src[i]].code);
     382             : 
     383      633600 :         src += width;
     384             :     }
     385             : 
     386             :     /* Pad output to a 32-bit boundary */
     387        2350 :     count = put_bits_count(&pb) & 0x1F;
     388             : 
     389        2350 :     if (count)
     390        2170 :         put_bits(&pb, 32 - count, 0);
     391             : 
     392             :     /* Get the amount of bits written */
     393        2350 :     count = put_bits_count(&pb);
     394             : 
     395             :     /* Flush the rest with zeroes */
     396        2350 :     flush_put_bits(&pb);
     397             : 
     398        2350 :     return count;
     399             : }
     400             : 
     401        2400 : static int encode_plane(AVCodecContext *avctx, uint8_t *src,
     402             :                         uint8_t *dst, ptrdiff_t stride, int plane_no,
     403             :                         int width, int height, PutByteContext *pb)
     404             : {
     405        2400 :     UtvideoContext *c        = avctx->priv_data;
     406             :     uint8_t  lengths[256];
     407        2400 :     uint64_t counts[256]     = { 0 };
     408             : 
     409             :     HuffEntry he[256];
     410             : 
     411        2400 :     uint32_t offset = 0, slice_len = 0;
     412        2400 :     const int cmask = ~(!plane_no && avctx->pix_fmt == AV_PIX_FMT_YUV420P);
     413        2400 :     int      i, sstart, send = 0;
     414             :     int      symbol;
     415             :     int      ret;
     416             : 
     417             :     /* Do prediction / make planes */
     418        2400 :     switch (c->frame_pred) {
     419         800 :     case PRED_NONE:
     420        1600 :         for (i = 0; i < c->slices; i++) {
     421         800 :             sstart = send;
     422         800 :             send   = height * (i + 1) / c->slices & cmask;
     423        1600 :             av_image_copy_plane(dst + sstart * width, width,
     424         800 :                                 src + sstart * stride, stride,
     425             :                                 width, send - sstart);
     426             :         }
     427         800 :         break;
     428         800 :     case PRED_LEFT:
     429        1600 :         for (i = 0; i < c->slices; i++) {
     430         800 :             sstart = send;
     431         800 :             send   = height * (i + 1) / c->slices & cmask;
     432         800 :             left_predict(src + sstart * stride, dst + sstart * width,
     433             :                          stride, width, send - sstart);
     434             :         }
     435         800 :         break;
     436         800 :     case PRED_MEDIAN:
     437        1600 :         for (i = 0; i < c->slices; i++) {
     438         800 :             sstart = send;
     439         800 :             send   = height * (i + 1) / c->slices & cmask;
     440         800 :             median_predict(c, src + sstart * stride, dst + sstart * width,
     441             :                            stride, width, send - sstart);
     442             :         }
     443         800 :         break;
     444           0 :     default:
     445           0 :         av_log(avctx, AV_LOG_ERROR, "Unknown prediction mode: %d\n",
     446             :                c->frame_pred);
     447           0 :         return AVERROR_OPTION_NOT_FOUND;
     448             :     }
     449             : 
     450             :     /* Count the usage of values */
     451        2400 :     count_usage(dst, width, height, counts);
     452             : 
     453             :     /* Check for a special case where only one symbol was used */
     454       16840 :     for (symbol = 0; symbol < 256; symbol++) {
     455             :         /* If non-zero count is found, see if it matches width * height */
     456       16840 :         if (counts[symbol]) {
     457             :             /* Special case if only one symbol was used */
     458        2400 :             if (counts[symbol] == width * (int64_t)height) {
     459             :                 /*
     460             :                  * Write a zero for the single symbol
     461             :                  * used in the plane, else 0xFF.
     462             :                  */
     463       12850 :                 for (i = 0; i < 256; i++) {
     464       12800 :                     if (i == symbol)
     465          50 :                         bytestream2_put_byte(pb, 0);
     466             :                     else
     467       12750 :                         bytestream2_put_byte(pb, 0xFF);
     468             :                 }
     469             : 
     470             :                 /* Write zeroes for lengths */
     471         100 :                 for (i = 0; i < c->slices; i++)
     472          50 :                     bytestream2_put_le32(pb, 0);
     473             : 
     474             :                 /* And that's all for that plane folks */
     475          50 :                 return 0;
     476             :             }
     477        2350 :             break;
     478             :         }
     479             :     }
     480             : 
     481             :     /* Calculate huffman lengths */
     482        2350 :     if ((ret = ff_huff_gen_len_table(lengths, counts, 256, 1)) < 0)
     483           0 :         return ret;
     484             : 
     485             :     /*
     486             :      * Write the plane's header into the output packet:
     487             :      * - huffman code lengths (256 bytes)
     488             :      * - slice end offsets (gotten from the slice lengths)
     489             :      */
     490      603950 :     for (i = 0; i < 256; i++) {
     491      601600 :         bytestream2_put_byte(pb, lengths[i]);
     492             : 
     493      601600 :         he[i].len = lengths[i];
     494      601600 :         he[i].sym = i;
     495             :     }
     496             : 
     497             :     /* Calculate the huffman codes themselves */
     498        2350 :     calculate_codes(he);
     499             : 
     500        2350 :     send = 0;
     501        4700 :     for (i = 0; i < c->slices; i++) {
     502        2350 :         sstart  = send;
     503        2350 :         send    = height * (i + 1) / c->slices & cmask;
     504             : 
     505             :         /*
     506             :          * Write the huffman codes to a buffer,
     507             :          * get the offset in bits and convert to bytes.
     508             :          */
     509        7050 :         offset += write_huff_codes(dst + sstart * width, c->slice_bits,
     510        2350 :                                    width * height + 4, width,
     511        2350 :                                    send - sstart, he) >> 3;
     512             : 
     513        2350 :         slice_len = offset - slice_len;
     514             : 
     515             :         /* Byteswap the written huffman codes */
     516        7050 :         c->bdsp.bswap_buf((uint32_t *) c->slice_bits,
     517        2350 :                           (uint32_t *) c->slice_bits,
     518        2350 :                           slice_len >> 2);
     519             : 
     520             :         /* Write the offset to the stream */
     521        2350 :         bytestream2_put_le32(pb, offset);
     522             : 
     523             :         /* Seek to the data part of the packet */
     524        4700 :         bytestream2_seek_p(pb, 4 * (c->slices - i - 1) +
     525        2350 :                            offset - slice_len, SEEK_CUR);
     526             : 
     527             :         /* Write the slices' data into the output packet */
     528        2350 :         bytestream2_put_buffer(pb, c->slice_bits, slice_len);
     529             : 
     530             :         /* Seek back to the slice offsets */
     531        2350 :         bytestream2_seek_p(pb, -4 * (c->slices - i - 1) - offset,
     532             :                            SEEK_CUR);
     533             : 
     534        2350 :         slice_len = offset;
     535             :     }
     536             : 
     537             :     /* And at the end seek to the end of written slice(s) */
     538        2350 :     bytestream2_seek_p(pb, offset, SEEK_CUR);
     539             : 
     540        2350 :     return 0;
     541             : }
     542             : 
     543         750 : static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     544             :                                 const AVFrame *pic, int *got_packet)
     545             : {
     546         750 :     UtvideoContext *c = avctx->priv_data;
     547             :     PutByteContext pb;
     548             : 
     549             :     uint32_t frame_info;
     550             : 
     551             :     uint8_t *dst;
     552             : 
     553         750 :     int width = avctx->width, height = avctx->height;
     554         750 :     int i, ret = 0;
     555             : 
     556             :     /* Allocate a new packet if needed, and set it to the pointer dst */
     557        2250 :     ret = ff_alloc_packet2(avctx, pkt, (256 + 4 * c->slices + width * height) *
     558        1500 :                            c->planes + 4, 0);
     559             : 
     560         750 :     if (ret < 0)
     561           0 :         return ret;
     562             : 
     563         750 :     dst = pkt->data;
     564             : 
     565         750 :     bytestream2_init_writer(&pb, dst, pkt->size);
     566             : 
     567         750 :     av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height + 4);
     568             : 
     569         750 :     if (!c->slice_bits) {
     570           0 :         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n");
     571           0 :         return AVERROR(ENOMEM);
     572             :     }
     573             : 
     574             :     /* In case of RGB, mangle the planes to Ut Video's format */
     575         750 :     if (avctx->pix_fmt == AV_PIX_FMT_RGBA || avctx->pix_fmt == AV_PIX_FMT_RGB24)
     576         300 :         mangle_rgb_planes(c->slice_buffer, c->slice_stride, pic->data[0],
     577         300 :                           c->planes, pic->linesize[0], width, height);
     578             : 
     579             :     /* Deal with the planes */
     580         750 :     switch (avctx->pix_fmt) {
     581         300 :     case AV_PIX_FMT_RGB24:
     582             :     case AV_PIX_FMT_RGBA:
     583        1350 :         for (i = 0; i < c->planes; i++) {
     584        1050 :             ret = encode_plane(avctx, c->slice_buffer[i] + 2 * c->slice_stride,
     585             :                                c->slice_buffer[i], c->slice_stride, i,
     586             :                                width, height, &pb);
     587             : 
     588        1050 :             if (ret) {
     589           0 :                 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
     590           0 :                 return ret;
     591             :             }
     592             :         }
     593         300 :         break;
     594         150 :     case AV_PIX_FMT_YUV444P:
     595         600 :         for (i = 0; i < c->planes; i++) {
     596         450 :             ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
     597         450 :                                pic->linesize[i], i, width, height, &pb);
     598             : 
     599         450 :             if (ret) {
     600           0 :                 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
     601           0 :                 return ret;
     602             :             }
     603             :         }
     604         150 :         break;
     605         150 :     case AV_PIX_FMT_YUV422P:
     606         600 :         for (i = 0; i < c->planes; i++) {
     607         900 :             ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
     608         900 :                                pic->linesize[i], i, width >> !!i, height, &pb);
     609             : 
     610         450 :             if (ret) {
     611           0 :                 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
     612           0 :                 return ret;
     613             :             }
     614             :         }
     615         150 :         break;
     616         150 :     case AV_PIX_FMT_YUV420P:
     617         600 :         for (i = 0; i < c->planes; i++) {
     618        1350 :             ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
     619        1350 :                                pic->linesize[i], i, width >> !!i, height >> !!i,
     620             :                                &pb);
     621             : 
     622         450 :             if (ret) {
     623           0 :                 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
     624           0 :                 return ret;
     625             :             }
     626             :         }
     627         150 :         break;
     628           0 :     default:
     629           0 :         av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
     630           0 :                avctx->pix_fmt);
     631           0 :         return AVERROR_INVALIDDATA;
     632             :     }
     633             : 
     634             :     /*
     635             :      * Write frame information (LE 32-bit unsigned)
     636             :      * into the output packet.
     637             :      * Contains the prediction method.
     638             :      */
     639         750 :     frame_info = c->frame_pred << 8;
     640         750 :     bytestream2_put_le32(&pb, frame_info);
     641             : 
     642             :     /*
     643             :      * At least currently Ut Video is IDR only.
     644             :      * Set flags accordingly.
     645             :      */
     646             : #if FF_API_CODED_FRAME
     647             : FF_DISABLE_DEPRECATION_WARNINGS
     648         750 :     avctx->coded_frame->key_frame = 1;
     649         750 :     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     650             : FF_ENABLE_DEPRECATION_WARNINGS
     651             : #endif
     652             : 
     653         750 :     pkt->size   = bytestream2_tell_p(&pb);
     654         750 :     pkt->flags |= AV_PKT_FLAG_KEY;
     655             : 
     656             :     /* Packet should be done */
     657         750 :     *got_packet = 1;
     658             : 
     659         750 :     return 0;
     660             : }
     661             : 
     662             : #define OFFSET(x) offsetof(UtvideoContext, x)
     663             : #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
     664             : static const AVOption options[] = {
     665             : { "pred", "Prediction method", OFFSET(frame_pred), AV_OPT_TYPE_INT, { .i64 = PRED_LEFT }, PRED_NONE, PRED_MEDIAN, VE, "pred" },
     666             :     { "none",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_NONE }, INT_MIN, INT_MAX, VE, "pred" },
     667             :     { "left",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_LEFT }, INT_MIN, INT_MAX, VE, "pred" },
     668             :     { "gradient", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_GRADIENT }, INT_MIN, INT_MAX, VE, "pred" },
     669             :     { "median",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRED_MEDIAN }, INT_MIN, INT_MAX, VE, "pred" },
     670             : 
     671             :     { NULL},
     672             : };
     673             : 
     674             : static const AVClass utvideo_class = {
     675             :     .class_name = "utvideo",
     676             :     .item_name  = av_default_item_name,
     677             :     .option     = options,
     678             :     .version    = LIBAVUTIL_VERSION_INT,
     679             : };
     680             : 
     681             : AVCodec ff_utvideo_encoder = {
     682             :     .name           = "utvideo",
     683             :     .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
     684             :     .type           = AVMEDIA_TYPE_VIDEO,
     685             :     .id             = AV_CODEC_ID_UTVIDEO,
     686             :     .priv_data_size = sizeof(UtvideoContext),
     687             :     .priv_class     = &utvideo_class,
     688             :     .init           = utvideo_encode_init,
     689             :     .encode2        = utvideo_encode_frame,
     690             :     .close          = utvideo_encode_close,
     691             :     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
     692             :     .pix_fmts       = (const enum AVPixelFormat[]) {
     693             :                           AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_YUV422P,
     694             :                           AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE
     695             :                       },
     696             : };

Generated by: LCOV version 1.13