libavcodec/r210enc.c
Go to the documentation of this file.
00001 /*
00002  * R210 encoder
00003  *
00004  * Copyright (c) 2012 Paul B Mahol
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include "avcodec.h"
00024 #include "bytestream.h"
00025 
00026 static av_cold int encode_init(AVCodecContext *avctx)
00027 {
00028     avctx->coded_frame = avcodec_alloc_frame();
00029 
00030     if (!avctx->coded_frame)
00031         return AVERROR(ENOMEM);
00032 
00033     return 0;
00034 }
00035 
00036 static int encode_frame(AVCodecContext *avctx, uint8_t *buf,
00037                         int buf_size, void *data)
00038 {
00039     AVFrame *pic = data;
00040     int i, j;
00041     int aligned_width = FFALIGN(avctx->width, 64);
00042     uint8_t *src_line;
00043     uint8_t *dst = buf;
00044 
00045     if (buf_size < 4 * aligned_width * avctx->height) {
00046         av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");
00047         return AVERROR(ENOMEM);
00048     }
00049 
00050     avctx->coded_frame->reference = 0;
00051     avctx->coded_frame->key_frame = 1;
00052     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00053     src_line = pic->data[0];
00054 
00055     for (i = 0; i < avctx->height; i++) {
00056         uint16_t *src = (uint16_t *)src_line;
00057         for (j = 0; j < avctx->width; j++) {
00058             uint32_t pixel;
00059             uint16_t r = *src++ >> 6;
00060             uint16_t g = *src++ >> 6;
00061             uint16_t b = *src++ >> 4;
00062             if (avctx->codec_id == CODEC_ID_R210)
00063                 pixel = (r << 20) | (g << 10) | b >> 2;
00064             else
00065                 pixel = (r << 22) | (g << 12) | b;
00066             if (avctx->codec_id == CODEC_ID_AVRP)
00067                 bytestream_put_le32(&dst, pixel);
00068             else
00069                 bytestream_put_be32(&dst, pixel);
00070         }
00071         dst += aligned_width - avctx->width;
00072         src_line += pic->linesize[0];
00073     }
00074 
00075     return 4 * aligned_width * avctx->height;
00076 }
00077 
00078 static av_cold int encode_close(AVCodecContext *avctx)
00079 {
00080     av_freep(&avctx->coded_frame);
00081 
00082     return 0;
00083 }
00084 
00085 #if CONFIG_R210_ENCODER
00086 AVCodec ff_r210_encoder = {
00087     .name           = "r210",
00088     .type           = AVMEDIA_TYPE_VIDEO,
00089     .id             = CODEC_ID_R210,
00090     .init           = encode_init,
00091     .encode         = encode_frame,
00092     .close          = encode_close,
00093     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE },
00094     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
00095 };
00096 #endif
00097 #if CONFIG_R10K_ENCODER
00098 AVCodec ff_r10k_encoder = {
00099     .name           = "r10k",
00100     .type           = AVMEDIA_TYPE_VIDEO,
00101     .id             = CODEC_ID_R10K,
00102     .init           = encode_init,
00103     .encode         = encode_frame,
00104     .close          = encode_close,
00105     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE },
00106     .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
00107 };
00108 #endif
00109 #if CONFIG_AVRP_ENCODER
00110 AVCodec ff_avrp_encoder = {
00111     .name           = "avrp",
00112     .type           = AVMEDIA_TYPE_VIDEO,
00113     .id             = CODEC_ID_AVRP,
00114     .init           = encode_init,
00115     .encode         = encode_frame,
00116     .close          = encode_close,
00117     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_RGB48, PIX_FMT_NONE },
00118     .long_name      = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
00119 };
00120 #endif