libavcodec/utvideo.c
Go to the documentation of this file.
00001 /*
00002  * Ut Video decoder
00003  * Copyright (c) 2011 Konstantin Shishkov
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00027 #include <stdlib.h>
00028 
00029 #include "libavutil/intreadwrite.h"
00030 #include "avcodec.h"
00031 #include "bytestream.h"
00032 #include "get_bits.h"
00033 #include "dsputil.h"
00034 #include "thread.h"
00035 
00036 enum {
00037     PRED_NONE = 0,
00038     PRED_LEFT,
00039     PRED_GRADIENT,
00040     PRED_MEDIAN,
00041 };
00042 
00043 typedef struct UtvideoContext {
00044     AVCodecContext *avctx;
00045     AVFrame pic;
00046     DSPContext dsp;
00047 
00048     uint32_t frame_info_size, flags, frame_info;
00049     int planes;
00050     int slices;
00051     int compression;
00052     int interlaced;
00053     int frame_pred;
00054 
00055     uint8_t *slice_bits;
00056     int slice_bits_size;
00057 } UtvideoContext;
00058 
00059 typedef struct HuffEntry {
00060     uint8_t sym;
00061     uint8_t len;
00062 } HuffEntry;
00063 
00064 static int huff_cmp(const void *a, const void *b)
00065 {
00066     const HuffEntry *aa = a, *bb = b;
00067     return (aa->len - bb->len)*256 + aa->sym - bb->sym;
00068 }
00069 
00070 static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
00071 {
00072     int i;
00073     HuffEntry he[256];
00074     int last;
00075     uint32_t codes[256];
00076     uint8_t bits[256];
00077     uint8_t syms[256];
00078     uint32_t code;
00079 
00080     *fsym = -1;
00081     for (i = 0; i < 256; i++) {
00082         he[i].sym = i;
00083         he[i].len = *src++;
00084     }
00085     qsort(he, 256, sizeof(*he), huff_cmp);
00086 
00087     if (!he[0].len) {
00088         *fsym = he[0].sym;
00089         return 0;
00090     }
00091     if (he[0].len > 32)
00092         return -1;
00093 
00094     last = 255;
00095     while (he[last].len == 255 && last)
00096         last--;
00097 
00098     code = 1;
00099     for (i = last; i >= 0; i--) {
00100         codes[i] = code >> (32 - he[i].len);
00101         bits[i]  = he[i].len;
00102         syms[i]  = he[i].sym;
00103         code += 0x80000000u >> (he[i].len - 1);
00104     }
00105 
00106     return init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1,
00107                            bits,  sizeof(*bits),  sizeof(*bits),
00108                            codes, sizeof(*codes), sizeof(*codes),
00109                            syms,  sizeof(*syms),  sizeof(*syms), 0);
00110 }
00111 
00112 static int decode_plane(UtvideoContext *c, int plane_no,
00113                         uint8_t *dst, int step, int stride,
00114                         int width, int height,
00115                         const uint8_t *src, int src_size, int use_pred)
00116 {
00117     int i, j, slice, pix;
00118     int sstart, send;
00119     VLC vlc;
00120     GetBitContext gb;
00121     int prev, fsym;
00122     const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
00123 
00124     if (build_huff(src, &vlc, &fsym)) {
00125         av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
00126         return AVERROR_INVALIDDATA;
00127     }
00128     if (fsym >= 0) { // build_huff reported a symbol to fill slices with
00129         send = 0;
00130         for (slice = 0; slice < c->slices; slice++) {
00131             uint8_t *dest;
00132 
00133             sstart = send;
00134             send   = (height * (slice + 1) / c->slices) & cmask;
00135             dest   = dst + sstart * stride;
00136 
00137             prev = 0x80;
00138             for (j = sstart; j < send; j++) {
00139                 for (i = 0; i < width * step; i += step) {
00140                     pix = fsym;
00141                     if (use_pred) {
00142                         prev += pix;
00143                         pix   = prev;
00144                     }
00145                     dest[i] = pix;
00146                 }
00147                 dest += stride;
00148             }
00149         }
00150         return 0;
00151     }
00152 
00153     src      += 256;
00154     src_size -= 256;
00155 
00156     send = 0;
00157     for (slice = 0; slice < c->slices; slice++) {
00158         uint8_t *dest;
00159         int slice_data_start, slice_data_end, slice_size;
00160 
00161         sstart = send;
00162         send   = (height * (slice + 1) / c->slices) & cmask;
00163         dest   = dst + sstart * stride;
00164 
00165         // slice offset and size validation was done earlier
00166         slice_data_start = slice ? AV_RL32(src + slice * 4 - 4) : 0;
00167         slice_data_end   = AV_RL32(src + slice * 4);
00168         slice_size       = slice_data_end - slice_data_start;
00169 
00170         if (!slice_size) {
00171             for (j = sstart; j < send; j++) {
00172                 for (i = 0; i < width * step; i += step)
00173                     dest[i] = 0x80;
00174                 dest += stride;
00175             }
00176             continue;
00177         }
00178 
00179         memcpy(c->slice_bits, src + slice_data_start + c->slices * 4, slice_size);
00180         memset(c->slice_bits + slice_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
00181         c->dsp.bswap_buf((uint32_t*)c->slice_bits, (uint32_t*)c->slice_bits,
00182                          (slice_data_end - slice_data_start + 3) >> 2);
00183         init_get_bits(&gb, c->slice_bits, slice_size * 8);
00184 
00185         prev = 0x80;
00186         for (j = sstart; j < send; j++) {
00187             for (i = 0; i < width * step; i += step) {
00188                 if (get_bits_left(&gb) <= 0) {
00189                     av_log(c->avctx, AV_LOG_ERROR, "Slice decoding ran out of bits\n");
00190                     goto fail;
00191                 }
00192                 pix = get_vlc2(&gb, vlc.table, vlc.bits, 4);
00193                 if (pix < 0) {
00194                     av_log(c->avctx, AV_LOG_ERROR, "Decoding error\n");
00195                     goto fail;
00196                 }
00197                 if (use_pred) {
00198                     prev += pix;
00199                     pix   = prev;
00200                 }
00201                 dest[i] = pix;
00202             }
00203             dest += stride;
00204         }
00205         if (get_bits_left(&gb) > 32)
00206             av_log(c->avctx, AV_LOG_WARNING, "%d bits left after decoding slice\n",
00207                    get_bits_left(&gb));
00208     }
00209 
00210     free_vlc(&vlc);
00211 
00212     return 0;
00213 fail:
00214     free_vlc(&vlc);
00215     return AVERROR_INVALIDDATA;
00216 }
00217 
00218 static const int rgb_order[4] = { 1, 2, 0, 3 };
00219 
00220 static void restore_rgb_planes(uint8_t *src, int step, int stride, int width, int height)
00221 {
00222     int i, j;
00223     uint8_t r, g, b;
00224 
00225     for (j = 0; j < height; j++) {
00226         for (i = 0; i < width * step; i += step) {
00227             r = src[i];
00228             g = src[i + 1];
00229             b = src[i + 2];
00230             src[i]     = r + g - 0x80;
00231             src[i + 2] = b + g - 0x80;
00232         }
00233         src += stride;
00234     }
00235 }
00236 
00237 static void restore_median(uint8_t *src, int step, int stride,
00238                            int width, int height, int slices, int rmode)
00239 {
00240     int i, j, slice;
00241     int A, B, C;
00242     uint8_t *bsrc;
00243     int slice_start, slice_height;
00244     const int cmask = ~rmode;
00245 
00246     for (slice = 0; slice < slices; slice++) {
00247         slice_start = ((slice * height) / slices) & cmask;
00248         slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start;
00249 
00250         bsrc = src + slice_start * stride;
00251 
00252         // first line - left neighbour prediction
00253         bsrc[0] += 0x80;
00254         A = bsrc[0];
00255         for (i = step; i < width * step; i += step) {
00256             bsrc[i] += A;
00257             A = bsrc[i];
00258         }
00259         bsrc += stride;
00260         if (slice_height == 1)
00261             continue;
00262         // second line - first element has top predition, the rest uses median
00263         C = bsrc[-stride];
00264         bsrc[0] += C;
00265         A = bsrc[0];
00266         for (i = step; i < width * step; i += step) {
00267             B = bsrc[i - stride];
00268             bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00269             C = B;
00270             A = bsrc[i];
00271         }
00272         bsrc += stride;
00273         // the rest of lines use continuous median prediction
00274         for (j = 2; j < slice_height; j++) {
00275             for (i = 0; i < width * step; i += step) {
00276                 B = bsrc[i - stride];
00277                 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00278                 C = B;
00279                 A = bsrc[i];
00280             }
00281             bsrc += stride;
00282         }
00283     }
00284 }
00285 
00286 /* UtVideo interlaced mode treats every two lines as a single one,
00287  * so restoring function should take care of possible padding between
00288  * two parts of the same "line".
00289  */
00290 static void restore_median_il(uint8_t *src, int step, int stride,
00291                               int width, int height, int slices, int rmode)
00292 {
00293     int i, j, slice;
00294     int A, B, C;
00295     uint8_t *bsrc;
00296     int slice_start, slice_height;
00297     const int cmask = ~(rmode ? 3 : 1);
00298     const int stride2 = stride << 1;
00299 
00300     for (slice = 0; slice < slices; slice++) {
00301         slice_start    = ((slice * height) / slices) & cmask;
00302         slice_height   = ((((slice + 1) * height) / slices) & cmask) - slice_start;
00303         slice_height >>= 1;
00304 
00305         bsrc = src + slice_start * stride;
00306 
00307         // first line - left neighbour prediction
00308         bsrc[0] += 0x80;
00309         A = bsrc[0];
00310         for (i = step; i < width * step; i += step) {
00311             bsrc[i] += A;
00312             A = bsrc[i];
00313         }
00314         for (i = 0; i < width * step; i += step) {
00315             bsrc[stride + i] += A;
00316             A = bsrc[stride + i];
00317         }
00318         bsrc += stride2;
00319         if (slice_height == 1)
00320             continue;
00321         // second line - first element has top predition, the rest uses median
00322         C = bsrc[-stride2];
00323         bsrc[0] += C;
00324         A = bsrc[0];
00325         for (i = step; i < width * step; i += step) {
00326             B = bsrc[i - stride2];
00327             bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00328             C = B;
00329             A = bsrc[i];
00330         }
00331         for (i = 0; i < width * step; i += step) {
00332             B = bsrc[i - stride];
00333             bsrc[stride + i] += mid_pred(A, B, (uint8_t)(A + B - C));
00334             C = B;
00335             A = bsrc[stride + i];
00336         }
00337         bsrc += stride2;
00338         // the rest of lines use continuous median prediction
00339         for (j = 2; j < slice_height; j++) {
00340             for (i = 0; i < width * step; i += step) {
00341                 B = bsrc[i - stride2];
00342                 bsrc[i] += mid_pred(A, B, (uint8_t)(A + B - C));
00343                 C = B;
00344                 A = bsrc[i];
00345             }
00346             for (i = 0; i < width * step; i += step) {
00347                 B = bsrc[i - stride];
00348                 bsrc[i + stride] += mid_pred(A, B, (uint8_t)(A + B - C));
00349                 C = B;
00350                 A = bsrc[i + stride];
00351             }
00352             bsrc += stride2;
00353         }
00354     }
00355 }
00356 
00357 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
00358 {
00359     const uint8_t *buf = avpkt->data;
00360     int buf_size = avpkt->size;
00361     const uint8_t *buf_end = buf + buf_size;
00362     UtvideoContext *c = avctx->priv_data;
00363     const uint8_t *ptr;
00364     int i, j;
00365     const uint8_t *plane_start[5];
00366     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
00367     int ret;
00368 
00369     if (c->pic.data[0])
00370         ff_thread_release_buffer(avctx, &c->pic);
00371 
00372     c->pic.reference = 1;
00373     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00374     if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) {
00375         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00376         return ret;
00377     }
00378 
00379     ff_thread_finish_setup(avctx);
00380 
00381     /* parse plane structure to retrieve frame flags and validate slice offsets */
00382     ptr = buf;
00383     for (i = 0; i < c->planes; i++) {
00384         plane_start[i] = ptr;
00385         if (buf_end - ptr < 256 + 4 * c->slices) {
00386             av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n");
00387             return AVERROR_INVALIDDATA;
00388         }
00389         ptr += 256;
00390         slice_start = 0;
00391         slice_end   = 0;
00392         for (j = 0; j < c->slices; j++) {
00393             slice_end   = bytestream_get_le32(&ptr);
00394             slice_size  = slice_end - slice_start;
00395             if (slice_size < 0) {
00396                 av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n");
00397                 return AVERROR_INVALIDDATA;
00398             }
00399             slice_start = slice_end;
00400             max_slice_size = FFMAX(max_slice_size, slice_size);
00401         }
00402         plane_size = slice_end;
00403         if (buf_end - ptr < plane_size) {
00404             av_log(avctx, AV_LOG_ERROR, "Plane size is bigger than available data\n");
00405             return AVERROR_INVALIDDATA;
00406         }
00407         ptr += plane_size;
00408     }
00409     plane_start[c->planes] = ptr;
00410     if (buf_end - ptr < c->frame_info_size) {
00411         av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n");
00412         return AVERROR_INVALIDDATA;
00413     }
00414     c->frame_info = AV_RL32(ptr);
00415     av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info);
00416 
00417     c->frame_pred = (c->frame_info >> 8) & 3;
00418 
00419     if (c->frame_pred == PRED_GRADIENT) {
00420         av_log_ask_for_sample(avctx, "Frame uses gradient prediction\n");
00421         return AVERROR_PATCHWELCOME;
00422     }
00423 
00424     av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
00425                    max_slice_size + FF_INPUT_BUFFER_PADDING_SIZE);
00426 
00427     if (!c->slice_bits) {
00428         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
00429         return AVERROR(ENOMEM);
00430     }
00431 
00432     switch (c->avctx->pix_fmt) {
00433     case PIX_FMT_RGB24:
00434     case PIX_FMT_RGBA:
00435         for (i = 0; i < c->planes; i++) {
00436             ret = decode_plane(c, i, c->pic.data[0] + rgb_order[i], c->planes,
00437                                c->pic.linesize[0], avctx->width, avctx->height,
00438                                plane_start[i], plane_start[i + 1] - plane_start[i],
00439                                c->frame_pred == PRED_LEFT);
00440             if (ret)
00441                 return ret;
00442             if (c->frame_pred == PRED_MEDIAN)
00443                 restore_median(c->pic.data[0] + rgb_order[i], c->planes,
00444                                c->pic.linesize[0], avctx->width, avctx->height,
00445                                c->slices, 0);
00446         }
00447         restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
00448                            avctx->width, avctx->height);
00449         break;
00450     case PIX_FMT_YUV420P:
00451         for (i = 0; i < 3; i++) {
00452             ret = decode_plane(c, i, c->pic.data[i], 1,
00453                                c->pic.linesize[i], avctx->width >> !!i, avctx->height >> !!i,
00454                                plane_start[i], plane_start[i + 1] - plane_start[i],
00455                                c->frame_pred == PRED_LEFT);
00456             if (ret)
00457                 return ret;
00458             if (c->frame_pred == PRED_MEDIAN) {
00459                 if (!c->interlaced) {
00460                     restore_median(c->pic.data[i], 1, c->pic.linesize[i],
00461                                    avctx->width >> !!i, avctx->height >> !!i,
00462                                    c->slices, !i);
00463                 } else {
00464                     restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
00465                                       avctx->width  >> !!i,
00466                                       avctx->height >> !!i,
00467                                       c->slices, !i);
00468                 }
00469             }
00470         }
00471         break;
00472     case PIX_FMT_YUV422P:
00473         for (i = 0; i < 3; i++) {
00474             ret = decode_plane(c, i, c->pic.data[i], 1,
00475                                c->pic.linesize[i], avctx->width >> !!i, avctx->height,
00476                                plane_start[i], plane_start[i + 1] - plane_start[i],
00477                                c->frame_pred == PRED_LEFT);
00478             if (ret)
00479                 return ret;
00480             if (c->frame_pred == PRED_MEDIAN) {
00481                 if (!c->interlaced) {
00482                     restore_median(c->pic.data[i], 1, c->pic.linesize[i],
00483                                    avctx->width >> !!i, avctx->height,
00484                                    c->slices, 0);
00485                 } else {
00486                     restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
00487                                       avctx->width >> !!i, avctx->height,
00488                                       c->slices, 0);
00489                 }
00490             }
00491         }
00492         break;
00493     }
00494 
00495     *data_size = sizeof(AVFrame);
00496     *(AVFrame*)data = c->pic;
00497 
00498     /* always report that the buffer was completely consumed */
00499     return buf_size;
00500 }
00501 
00502 static av_cold int decode_init(AVCodecContext *avctx)
00503 {
00504     UtvideoContext * const c = avctx->priv_data;
00505 
00506     c->avctx = avctx;
00507 
00508     dsputil_init(&c->dsp, avctx);
00509 
00510     if (avctx->extradata_size < 16) {
00511         av_log(avctx, AV_LOG_ERROR, "Insufficient extradata size %d, should be at least 16\n",
00512                avctx->extradata_size);
00513         return AVERROR_INVALIDDATA;
00514     }
00515 
00516     av_log(avctx, AV_LOG_DEBUG, "Encoder version %d.%d.%d.%d\n",
00517            avctx->extradata[3], avctx->extradata[2],
00518            avctx->extradata[1], avctx->extradata[0]);
00519     av_log(avctx, AV_LOG_DEBUG, "Original format %X\n", AV_RB32(avctx->extradata + 4));
00520     c->frame_info_size = AV_RL32(avctx->extradata + 8);
00521     c->flags           = AV_RL32(avctx->extradata + 12);
00522 
00523     if (c->frame_info_size != 4)
00524         av_log_ask_for_sample(avctx, "Frame info is not 4 bytes\n");
00525     av_log(avctx, AV_LOG_DEBUG, "Encoding parameters %08X\n", c->flags);
00526     c->slices      = (c->flags >> 24) + 1;
00527     c->compression = c->flags & 1;
00528     c->interlaced  = c->flags & 0x800;
00529 
00530     c->slice_bits_size = 0;
00531 
00532     switch (avctx->codec_tag) {
00533     case MKTAG('U', 'L', 'R', 'G'):
00534         c->planes      = 3;
00535         avctx->pix_fmt = PIX_FMT_RGB24;
00536         break;
00537     case MKTAG('U', 'L', 'R', 'A'):
00538         c->planes      = 4;
00539         avctx->pix_fmt = PIX_FMT_RGBA;
00540         break;
00541     case MKTAG('U', 'L', 'Y', '0'):
00542         c->planes      = 3;
00543         avctx->pix_fmt = PIX_FMT_YUV420P;
00544         break;
00545     case MKTAG('U', 'L', 'Y', '2'):
00546         c->planes      = 3;
00547         avctx->pix_fmt = PIX_FMT_YUV422P;
00548         break;
00549     default:
00550         av_log(avctx, AV_LOG_ERROR, "Unknown Ut Video FOURCC provided (%08X)\n",
00551                avctx->codec_tag);
00552         return AVERROR_INVALIDDATA;
00553     }
00554 
00555     return 0;
00556 }
00557 
00558 static av_cold int decode_end(AVCodecContext *avctx)
00559 {
00560     UtvideoContext * const c = avctx->priv_data;
00561 
00562     if (c->pic.data[0])
00563         ff_thread_release_buffer(avctx, &c->pic);
00564 
00565     av_freep(&c->slice_bits);
00566 
00567     return 0;
00568 }
00569 
00570 AVCodec ff_utvideo_decoder = {
00571     .name           = "utvideo",
00572     .type           = AVMEDIA_TYPE_VIDEO,
00573     .id             = CODEC_ID_UTVIDEO,
00574     .priv_data_size = sizeof(UtvideoContext),
00575     .init           = decode_init,
00576     .close          = decode_end,
00577     .decode         = decode_frame,
00578     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
00579     .long_name      = NULL_IF_CONFIG_SMALL("Ut Video"),
00580 };
00581