00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "avcodec.h"
00024 #include "put_bits.h"
00025
00026 static av_cold int v410_encode_init(AVCodecContext *avctx)
00027 {
00028 if (avctx->width & 1) {
00029 av_log(avctx, AV_LOG_ERROR, "v410 requires width to be even.\n");
00030 return AVERROR_INVALIDDATA;
00031 }
00032
00033 avctx->coded_frame = avcodec_alloc_frame();
00034
00035 if (!avctx->coded_frame) {
00036 av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
00037 return AVERROR(ENOMEM);
00038 }
00039
00040 return 0;
00041 }
00042
00043 static int v410_encode_frame(AVCodecContext *avctx, uint8_t *buf,
00044 int buf_size, void *data)
00045 {
00046 AVFrame *pic = data;
00047 uint8_t *dst = buf;
00048 uint16_t *y, *u, *v;
00049 uint32_t val;
00050 int i, j;
00051 int output_size = 0;
00052
00053 if (buf_size < avctx->width * avctx->height * 4) {
00054 av_log(avctx, AV_LOG_ERROR, "Out buffer is too small.\n");
00055 return AVERROR(ENOMEM);
00056 }
00057
00058 avctx->coded_frame->reference = 0;
00059 avctx->coded_frame->key_frame = 1;
00060 avctx->coded_frame->pict_type = FF_I_TYPE;
00061
00062 y = (uint16_t *)pic->data[0];
00063 u = (uint16_t *)pic->data[1];
00064 v = (uint16_t *)pic->data[2];
00065
00066 for (i = 0; i < avctx->height; i++) {
00067 for (j = 0; j < avctx->width; j++) {
00068 val = u[j] << 2;
00069 val |= y[j] << 12;
00070 val |= v[j] << 22;
00071 AV_WL32(dst, val);
00072 dst += 4;
00073 output_size += 4;
00074 }
00075 y += pic->linesize[0] >> 1;
00076 u += pic->linesize[1] >> 1;
00077 v += pic->linesize[2] >> 1;
00078 }
00079
00080 return output_size;
00081 }
00082
00083 static av_cold int v410_encode_close(AVCodecContext *avctx)
00084 {
00085 av_freep(&avctx->coded_frame);
00086
00087 return 0;
00088 }
00089
00090 AVCodec ff_v410_encoder = {
00091 .name = "v410",
00092 .type = AVMEDIA_TYPE_VIDEO,
00093 .id = CODEC_ID_V410,
00094 .init = v410_encode_init,
00095 .encode = v410_encode_frame,
00096 .close = v410_encode_close,
00097 .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_YUV444P10, PIX_FMT_NONE },
00098 .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
00099 };