00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/intreadwrite.h"
00028 #include "avcodec.h"
00029 #include "internal.h"
00030 #include "bytestream.h"
00031 #include "put_bits.h"
00032 #include "dsputil.h"
00033 #include "mathops.h"
00034 #include "utvideo.h"
00035 #include "huffman.h"
00036
00037
00038 static int huff_cmp_sym(const void *a, const void *b)
00039 {
00040 const HuffEntry *aa = a, *bb = b;
00041 return aa->sym - bb->sym;
00042 }
00043
00044 static av_cold int utvideo_encode_close(AVCodecContext *avctx)
00045 {
00046 UtvideoContext *c = avctx->priv_data;
00047 int i;
00048
00049 av_freep(&avctx->coded_frame);
00050 av_freep(&c->slice_bits);
00051 for (i = 0; i < 4; i++)
00052 av_freep(&c->slice_buffer[i]);
00053
00054 return 0;
00055 }
00056
00057 static av_cold int utvideo_encode_init(AVCodecContext *avctx)
00058 {
00059 UtvideoContext *c = avctx->priv_data;
00060 int i;
00061 uint32_t original_format;
00062
00063 c->avctx = avctx;
00064 c->frame_info_size = 4;
00065 c->slice_stride = FFALIGN(avctx->width, 32);
00066
00067 switch (avctx->pix_fmt) {
00068 case PIX_FMT_RGB24:
00069 c->planes = 3;
00070 avctx->codec_tag = MKTAG('U', 'L', 'R', 'G');
00071 original_format = UTVIDEO_RGB;
00072 break;
00073 case PIX_FMT_RGBA:
00074 c->planes = 4;
00075 avctx->codec_tag = MKTAG('U', 'L', 'R', 'A');
00076 original_format = UTVIDEO_RGBA;
00077 break;
00078 case PIX_FMT_YUV420P:
00079 if (avctx->width & 1 || avctx->height & 1) {
00080 av_log(avctx, AV_LOG_ERROR,
00081 "4:2:0 video requires even width and height.\n");
00082 return AVERROR_INVALIDDATA;
00083 }
00084 c->planes = 3;
00085 avctx->codec_tag = MKTAG('U', 'L', 'Y', '0');
00086 original_format = UTVIDEO_420;
00087 break;
00088 case PIX_FMT_YUV422P:
00089 if (avctx->width & 1) {
00090 av_log(avctx, AV_LOG_ERROR,
00091 "4:2:2 video requires even width.\n");
00092 return AVERROR_INVALIDDATA;
00093 }
00094 c->planes = 3;
00095 avctx->codec_tag = MKTAG('U', 'L', 'Y', '2');
00096 original_format = UTVIDEO_422;
00097 break;
00098 default:
00099 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
00100 avctx->pix_fmt);
00101 return AVERROR_INVALIDDATA;
00102 }
00103
00104 ff_dsputil_init(&c->dsp, avctx);
00105
00106
00107 if (avctx->prediction_method < 0 || avctx->prediction_method > 4) {
00108 av_log(avctx, AV_LOG_WARNING,
00109 "Prediction method %d is not supported in Ut Video.\n",
00110 avctx->prediction_method);
00111 return AVERROR_OPTION_NOT_FOUND;
00112 }
00113
00114 if (avctx->prediction_method == FF_PRED_PLANE) {
00115 av_log(avctx, AV_LOG_ERROR,
00116 "Plane prediction is not supported in Ut Video.\n");
00117 return AVERROR_OPTION_NOT_FOUND;
00118 }
00119
00120
00121 c->frame_pred = ff_ut_pred_order[avctx->prediction_method];
00122
00123 if (c->frame_pred == PRED_GRADIENT) {
00124 av_log(avctx, AV_LOG_ERROR, "Gradient prediction is not supported.\n");
00125 return AVERROR_OPTION_NOT_FOUND;
00126 }
00127
00128 avctx->coded_frame = avcodec_alloc_frame();
00129
00130 if (!avctx->coded_frame) {
00131 av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
00132 utvideo_encode_close(avctx);
00133 return AVERROR(ENOMEM);
00134 }
00135
00136
00137 avctx->extradata_size = 16;
00138
00139 avctx->extradata = av_mallocz(avctx->extradata_size +
00140 FF_INPUT_BUFFER_PADDING_SIZE);
00141
00142 if (!avctx->extradata) {
00143 av_log(avctx, AV_LOG_ERROR, "Could not allocate extradata.\n");
00144 utvideo_encode_close(avctx);
00145 return AVERROR(ENOMEM);
00146 }
00147
00148 for (i = 0; i < c->planes; i++) {
00149 c->slice_buffer[i] = av_malloc(c->slice_stride * (avctx->height + 2) +
00150 FF_INPUT_BUFFER_PADDING_SIZE);
00151 if (!c->slice_buffer[i]) {
00152 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 1.\n");
00153 utvideo_encode_close(avctx);
00154 return AVERROR(ENOMEM);
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 AV_WB32(avctx->extradata, MKTAG(1, 0, 0, 0xF0));
00165
00166
00167
00168
00169
00170 AV_WL32(avctx->extradata + 4, original_format);
00171
00172
00173 AV_WL32(avctx->extradata + 8, c->frame_info_size);
00174
00175
00176
00177
00178
00179 c->slices = 1;
00180
00181
00182 c->compression = COMP_HUFF;
00183
00184
00185
00186
00187
00188
00189
00190
00191 c->flags = (c->slices - 1) << 24;
00192 c->flags |= 0 << 11;
00193 c->flags |= c->compression;
00194
00195 AV_WL32(avctx->extradata + 12, c->flags);
00196
00197 return 0;
00198 }
00199
00200 static void mangle_rgb_planes(uint8_t *dst[4], int dst_stride, uint8_t *src,
00201 int step, int stride, int width, int height)
00202 {
00203 int i, j;
00204 int k = 2 * dst_stride;
00205 unsigned int g;
00206
00207 for (j = 0; j < height; j++) {
00208 if (step == 3) {
00209 for (i = 0; i < width * step; i += step) {
00210 g = src[i + 1];
00211 dst[0][k] = g;
00212 g += 0x80;
00213 dst[1][k] = src[i + 2] - g;
00214 dst[2][k] = src[i + 0] - g;
00215 k++;
00216 }
00217 } else {
00218 for (i = 0; i < width * step; i += step) {
00219 g = src[i + 1];
00220 dst[0][k] = g;
00221 g += 0x80;
00222 dst[1][k] = src[i + 2] - g;
00223 dst[2][k] = src[i + 0] - g;
00224 dst[3][k] = src[i + 3];
00225 k++;
00226 }
00227 }
00228 k += dst_stride - width;
00229 src += stride;
00230 }
00231 }
00232
00233
00234 static void write_plane(uint8_t *src, uint8_t *dst, int stride,
00235 int width, int height)
00236 {
00237 int i, j;
00238
00239 for (j = 0; j < height; j++) {
00240 for (i = 0; i < width; i++)
00241 *dst++ = src[i];
00242
00243 src += stride;
00244 }
00245 }
00246
00247
00248 static void left_predict(uint8_t *src, uint8_t *dst, int stride,
00249 int width, int height)
00250 {
00251 int i, j;
00252 uint8_t prev;
00253
00254 prev = 0x80;
00255 for (j = 0; j < height; j++) {
00256 for (i = 0; i < width; i++) {
00257 *dst++ = src[i] - prev;
00258 prev = src[i];
00259 }
00260 src += stride;
00261 }
00262 }
00263
00264
00265 static void median_predict(UtvideoContext *c, uint8_t *src, uint8_t *dst, int stride,
00266 int width, int height)
00267 {
00268 int i, j;
00269 int A, B;
00270 uint8_t prev;
00271
00272
00273 prev = 0x80;
00274 for (i = 0; i < width; i++) {
00275 *dst++ = src[i] - prev;
00276 prev = src[i];
00277 }
00278
00279 if (height == 1)
00280 return;
00281
00282 src += stride;
00283
00284
00285
00286
00287
00288 A = B = 0;
00289
00290
00291 for (j = 1; j < height; j++) {
00292 c->dsp.sub_hfyu_median_prediction(dst, src - stride, src, width, &A, &B);
00293 dst += width;
00294 src += stride;
00295 }
00296 }
00297
00298
00299 static void count_usage(uint8_t *src, int width,
00300 int height, uint64_t *counts)
00301 {
00302 int i, j;
00303
00304 for (j = 0; j < height; j++) {
00305 for (i = 0; i < width; i++) {
00306 counts[src[i]]++;
00307 }
00308 src += width;
00309 }
00310 }
00311
00312
00313 static void calculate_codes(HuffEntry *he)
00314 {
00315 int last, i;
00316 uint32_t code;
00317
00318 qsort(he, 256, sizeof(*he), ff_ut_huff_cmp_len);
00319
00320 last = 255;
00321 while (he[last].len == 255 && last)
00322 last--;
00323
00324 code = 1;
00325 for (i = last; i >= 0; i--) {
00326 he[i].code = code >> (32 - he[i].len);
00327 code += 0x80000000u >> (he[i].len - 1);
00328 }
00329
00330 qsort(he, 256, sizeof(*he), huff_cmp_sym);
00331 }
00332
00333
00334 static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size,
00335 int width, int height, HuffEntry *he)
00336 {
00337 PutBitContext pb;
00338 int i, j;
00339 int count;
00340
00341 init_put_bits(&pb, dst, dst_size);
00342
00343
00344 for (j = 0; j < height; j++) {
00345 for (i = 0; i < width; i++)
00346 put_bits(&pb, he[src[i]].len, he[src[i]].code);
00347
00348 src += width;
00349 }
00350
00351
00352 count = put_bits_count(&pb) & 0x1F;
00353
00354 if (count)
00355 put_bits(&pb, 32 - count, 0);
00356
00357
00358 count = put_bits_count(&pb);
00359
00360
00361 flush_put_bits(&pb);
00362
00363 return count;
00364 }
00365
00366 static int encode_plane(AVCodecContext *avctx, uint8_t *src,
00367 uint8_t *dst, int stride,
00368 int width, int height, PutByteContext *pb)
00369 {
00370 UtvideoContext *c = avctx->priv_data;
00371 uint8_t lengths[256];
00372 uint64_t counts[256] = { 0 };
00373
00374 HuffEntry he[256];
00375
00376 uint32_t offset = 0, slice_len = 0;
00377 int i, sstart, send = 0;
00378 int symbol;
00379
00380
00381 switch (c->frame_pred) {
00382 case PRED_NONE:
00383 for (i = 0; i < c->slices; i++) {
00384 sstart = send;
00385 send = height * (i + 1) / c->slices;
00386 write_plane(src + sstart * stride, dst + sstart * width,
00387 stride, width, send - sstart);
00388 }
00389 break;
00390 case PRED_LEFT:
00391 for (i = 0; i < c->slices; i++) {
00392 sstart = send;
00393 send = height * (i + 1) / c->slices;
00394 left_predict(src + sstart * stride, dst + sstart * width,
00395 stride, width, send - sstart);
00396 }
00397 break;
00398 case PRED_MEDIAN:
00399 for (i = 0; i < c->slices; i++) {
00400 sstart = send;
00401 send = height * (i + 1) / c->slices;
00402 median_predict(c, src + sstart * stride, dst + sstart * width,
00403 stride, width, send - sstart);
00404 }
00405 break;
00406 default:
00407 av_log(avctx, AV_LOG_ERROR, "Unknown prediction mode: %d\n",
00408 c->frame_pred);
00409 return AVERROR_OPTION_NOT_FOUND;
00410 }
00411
00412
00413 count_usage(dst, width, height, counts);
00414
00415
00416 for (symbol = 0; symbol < 256; symbol++) {
00417
00418 if (counts[symbol]) {
00419
00420 if (counts[symbol] == width * height) {
00421
00422
00423
00424
00425 for (i = 0; i < 256; i++) {
00426 if (i == symbol)
00427 bytestream2_put_byte(pb, 0);
00428 else
00429 bytestream2_put_byte(pb, 0xFF);
00430 }
00431
00432
00433 for (i = 0; i < c->slices; i++)
00434 bytestream2_put_le32(pb, 0);
00435
00436
00437 return 0;
00438 }
00439 break;
00440 }
00441 }
00442
00443
00444 ff_huff_gen_len_table(lengths, counts);
00445
00446
00447
00448
00449
00450
00451 for (i = 0; i < 256; i++) {
00452 bytestream2_put_byte(pb, lengths[i]);
00453
00454 he[i].len = lengths[i];
00455 he[i].sym = i;
00456 }
00457
00458
00459 calculate_codes(he);
00460
00461 send = 0;
00462 for (i = 0; i < c->slices; i++) {
00463 sstart = send;
00464 send = height * (i + 1) / c->slices;
00465
00466
00467
00468
00469
00470 offset += write_huff_codes(dst + sstart * width, c->slice_bits,
00471 width * (send - sstart), width,
00472 send - sstart, he) >> 3;
00473
00474 slice_len = offset - slice_len;
00475
00476
00477 c->dsp.bswap_buf((uint32_t *) c->slice_bits,
00478 (uint32_t *) c->slice_bits,
00479 slice_len >> 2);
00480
00481
00482 bytestream2_put_le32(pb, offset);
00483
00484
00485 bytestream2_seek_p(pb, 4 * (c->slices - i - 1) +
00486 offset - slice_len, SEEK_CUR);
00487
00488
00489 bytestream2_put_buffer(pb, c->slice_bits, slice_len);
00490
00491
00492 bytestream2_seek_p(pb, -4 * (c->slices - i - 1) - offset,
00493 SEEK_CUR);
00494
00495 slice_len = offset;
00496 }
00497
00498
00499 bytestream2_seek_p(pb, offset, SEEK_CUR);
00500
00501 return 0;
00502 }
00503
00504 static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00505 const AVFrame *pic, int *got_packet)
00506 {
00507 UtvideoContext *c = avctx->priv_data;
00508 PutByteContext pb;
00509
00510 uint32_t frame_info;
00511
00512 uint8_t *dst;
00513
00514 int width = avctx->width, height = avctx->height;
00515 int i, ret = 0;
00516
00517
00518 ret = ff_alloc_packet2(avctx, pkt, (256 + 4 * c->slices + width * height) *
00519 c->planes + 4);
00520
00521 if (ret < 0)
00522 return ret;
00523
00524 dst = pkt->data;
00525
00526 bytestream2_init_writer(&pb, dst, pkt->size);
00527
00528 av_fast_malloc(&c->slice_bits, &c->slice_bits_size,
00529 width * height + FF_INPUT_BUFFER_PADDING_SIZE);
00530
00531 if (!c->slice_bits) {
00532 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n");
00533 return AVERROR(ENOMEM);
00534 }
00535
00536
00537 if (avctx->pix_fmt == PIX_FMT_RGBA || avctx->pix_fmt == PIX_FMT_RGB24)
00538 mangle_rgb_planes(c->slice_buffer, c->slice_stride, pic->data[0],
00539 c->planes, pic->linesize[0], width, height);
00540
00541
00542 switch (avctx->pix_fmt) {
00543 case PIX_FMT_RGB24:
00544 case PIX_FMT_RGBA:
00545 for (i = 0; i < c->planes; i++) {
00546 ret = encode_plane(avctx, c->slice_buffer[i] + 2 * c->slice_stride,
00547 c->slice_buffer[i], c->slice_stride,
00548 width, height, &pb);
00549
00550 if (ret) {
00551 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
00552 return ret;
00553 }
00554 }
00555 break;
00556 case PIX_FMT_YUV422P:
00557 for (i = 0; i < c->planes; i++) {
00558 ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
00559 pic->linesize[i], width >> !!i, height, &pb);
00560
00561 if (ret) {
00562 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
00563 return ret;
00564 }
00565 }
00566 break;
00567 case PIX_FMT_YUV420P:
00568 for (i = 0; i < c->planes; i++) {
00569 ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0],
00570 pic->linesize[i], width >> !!i, height >> !!i,
00571 &pb);
00572
00573 if (ret) {
00574 av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i);
00575 return ret;
00576 }
00577 }
00578 break;
00579 default:
00580 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format: %d\n",
00581 avctx->pix_fmt);
00582 return AVERROR_INVALIDDATA;
00583 }
00584
00585
00586
00587
00588
00589
00590 frame_info = c->frame_pred << 8;
00591 bytestream2_put_le32(&pb, frame_info);
00592
00593
00594
00595
00596
00597 avctx->coded_frame->reference = 0;
00598 avctx->coded_frame->key_frame = 1;
00599 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00600
00601 pkt->size = bytestream2_tell_p(&pb);
00602 pkt->flags |= AV_PKT_FLAG_KEY;
00603
00604
00605 *got_packet = 1;
00606
00607 return 0;
00608 }
00609
00610 AVCodec ff_utvideo_encoder = {
00611 .name = "utvideo",
00612 .type = AVMEDIA_TYPE_VIDEO,
00613 .id = AV_CODEC_ID_UTVIDEO,
00614 .priv_data_size = sizeof(UtvideoContext),
00615 .init = utvideo_encode_init,
00616 .encode2 = utvideo_encode_frame,
00617 .close = utvideo_encode_close,
00618 .pix_fmts = (const enum PixelFormat[]) {
00619 PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_YUV422P,
00620 PIX_FMT_YUV420P, PIX_FMT_NONE
00621 },
00622 .long_name = NULL_IF_CONFIG_SMALL("Ut Video"),
00623 };