xref: /third_party/ffmpeg/libavcodec/r210enc.c (revision cabdff1a)
1/*
2 * R210 encoder
3 *
4 * Copyright (c) 2012 Paul B Mahol
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "config_components.h"
24
25#include "avcodec.h"
26#include "codec_internal.h"
27#include "encode.h"
28#include "internal.h"
29#include "bytestream.h"
30
31static av_cold int encode_init(AVCodecContext *avctx)
32{
33    int aligned_width = FFALIGN(avctx->width,
34                                avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64);
35
36    avctx->bits_per_coded_sample = 32;
37    if (avctx->width > 0)
38        avctx->bit_rate = ff_guess_coded_bitrate(avctx) * aligned_width / avctx->width;
39
40    return 0;
41}
42
43static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
44                        const AVFrame *pic, int *got_packet)
45{
46    int i, j, ret;
47    int aligned_width = FFALIGN(avctx->width,
48                                avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64);
49    int pad = (aligned_width - avctx->width) * 4;
50    uint8_t *srcr_line, *srcg_line, *srcb_line;
51    uint8_t *dst;
52
53    ret = ff_get_encode_buffer(avctx, pkt, 4 * aligned_width * avctx->height, 0);
54    if (ret < 0)
55        return ret;
56
57    srcg_line = pic->data[0];
58    srcb_line = pic->data[1];
59    srcr_line = pic->data[2];
60    dst = pkt->data;
61
62    for (i = 0; i < avctx->height; i++) {
63        uint16_t *srcr = (uint16_t *)srcr_line;
64        uint16_t *srcg = (uint16_t *)srcg_line;
65        uint16_t *srcb = (uint16_t *)srcb_line;
66        for (j = 0; j < avctx->width; j++) {
67            uint32_t pixel;
68            unsigned r = *srcr++;
69            unsigned g = *srcg++;
70            unsigned b = *srcb++;
71            if (avctx->codec_id == AV_CODEC_ID_R210)
72                pixel = (r << 20) | (g << 10) | b;
73            else
74                pixel = (r << 22) | (g << 12) | (b << 2);
75            if (avctx->codec_id == AV_CODEC_ID_AVRP)
76                bytestream_put_le32(&dst, pixel);
77            else
78                bytestream_put_be32(&dst, pixel);
79        }
80        memset(dst, 0, pad);
81        dst += pad;
82        srcr_line += pic->linesize[2];
83        srcg_line += pic->linesize[0];
84        srcb_line += pic->linesize[1];
85    }
86
87    *got_packet = 1;
88    return 0;
89}
90
91static const enum AVPixelFormat pix_fmt[] = { AV_PIX_FMT_GBRP10, AV_PIX_FMT_NONE };
92
93#if CONFIG_R210_ENCODER
94const FFCodec ff_r210_encoder = {
95    .p.name         = "r210",
96    .p.long_name    = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
97    .p.type         = AVMEDIA_TYPE_VIDEO,
98    .p.id           = AV_CODEC_ID_R210,
99    .p.capabilities = AV_CODEC_CAP_DR1,
100    .init           = encode_init,
101    FF_CODEC_ENCODE_CB(encode_frame),
102    .p.pix_fmts     = pix_fmt,
103    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
104};
105#endif
106#if CONFIG_R10K_ENCODER
107const FFCodec ff_r10k_encoder = {
108    .p.name         = "r10k",
109    .p.long_name    = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
110    .p.type         = AVMEDIA_TYPE_VIDEO,
111    .p.id           = AV_CODEC_ID_R10K,
112    .p.capabilities = AV_CODEC_CAP_DR1,
113    .init           = encode_init,
114    FF_CODEC_ENCODE_CB(encode_frame),
115    .p.pix_fmts     = pix_fmt,
116    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
117};
118#endif
119#if CONFIG_AVRP_ENCODER
120const FFCodec ff_avrp_encoder = {
121    .p.name         = "avrp",
122    .p.long_name    = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
123    .p.type         = AVMEDIA_TYPE_VIDEO,
124    .p.id           = AV_CODEC_ID_AVRP,
125    .p.capabilities = AV_CODEC_CAP_DR1,
126    .init           = encode_init,
127    FF_CODEC_ENCODE_CB(encode_frame),
128    .p.pix_fmts     = pix_fmt,
129    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
130};
131#endif
132