1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * V210 encoder
3cabdff1aSopenharmony_ci *
4cabdff1aSopenharmony_ci * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
5cabdff1aSopenharmony_ci * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * This file is part of FFmpeg.
8cabdff1aSopenharmony_ci *
9cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
10cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
11cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
12cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
13cabdff1aSopenharmony_ci *
14cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
15cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
16cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17cabdff1aSopenharmony_ci * Lesser General Public License for more details.
18cabdff1aSopenharmony_ci *
19cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
20cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
21cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22cabdff1aSopenharmony_ci */
23cabdff1aSopenharmony_ci
24cabdff1aSopenharmony_ci#include "avcodec.h"
25cabdff1aSopenharmony_ci#include "bytestream.h"
26cabdff1aSopenharmony_ci#include "codec_internal.h"
27cabdff1aSopenharmony_ci#include "encode.h"
28cabdff1aSopenharmony_ci#include "internal.h"
29cabdff1aSopenharmony_ci#include "v210enc.h"
30cabdff1aSopenharmony_ci#include "v210enc_init.h"
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#define TYPE uint8_t
33cabdff1aSopenharmony_ci#define DEPTH 8
34cabdff1aSopenharmony_ci#define BYTES_PER_PIXEL 1
35cabdff1aSopenharmony_ci#define RENAME(a) a ## _ ## 8
36cabdff1aSopenharmony_ci#include "v210_template.c"
37cabdff1aSopenharmony_ci#undef RENAME
38cabdff1aSopenharmony_ci#undef DEPTH
39cabdff1aSopenharmony_ci#undef BYTES_PER_PIXEL
40cabdff1aSopenharmony_ci#undef TYPE
41cabdff1aSopenharmony_ci
42cabdff1aSopenharmony_ci#define TYPE uint16_t
43cabdff1aSopenharmony_ci#define DEPTH 10
44cabdff1aSopenharmony_ci#define BYTES_PER_PIXEL 2
45cabdff1aSopenharmony_ci#define RENAME(a) a ## _ ## 10
46cabdff1aSopenharmony_ci#include "v210_template.c"
47cabdff1aSopenharmony_ci#undef RENAME
48cabdff1aSopenharmony_ci#undef DEPTH
49cabdff1aSopenharmony_ci#undef BYTES_PER_PIXEL
50cabdff1aSopenharmony_ci#undef TYPE
51cabdff1aSopenharmony_ci
52cabdff1aSopenharmony_cistatic av_cold int encode_init(AVCodecContext *avctx)
53cabdff1aSopenharmony_ci{
54cabdff1aSopenharmony_ci    V210EncContext *s = avctx->priv_data;
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci    if (avctx->width & 1) {
57cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
58cabdff1aSopenharmony_ci        return AVERROR(EINVAL);
59cabdff1aSopenharmony_ci    }
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci    ff_v210enc_init(s);
62cabdff1aSopenharmony_ci
63cabdff1aSopenharmony_ci    avctx->bits_per_coded_sample = 20;
64cabdff1aSopenharmony_ci    avctx->bit_rate = ff_guess_coded_bitrate(avctx) * 16 / 15;
65cabdff1aSopenharmony_ci
66cabdff1aSopenharmony_ci    return 0;
67cabdff1aSopenharmony_ci}
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_cistatic int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
70cabdff1aSopenharmony_ci                        const AVFrame *pic, int *got_packet)
71cabdff1aSopenharmony_ci{
72cabdff1aSopenharmony_ci    int aligned_width = ((avctx->width + 47) / 48) * 48;
73cabdff1aSopenharmony_ci    int stride = aligned_width * 8 / 3;
74cabdff1aSopenharmony_ci    AVFrameSideData *side_data;
75cabdff1aSopenharmony_ci    int ret;
76cabdff1aSopenharmony_ci    uint8_t *dst;
77cabdff1aSopenharmony_ci
78cabdff1aSopenharmony_ci    ret = ff_get_encode_buffer(avctx, pkt, avctx->height * stride, 0);
79cabdff1aSopenharmony_ci    if (ret < 0) {
80cabdff1aSopenharmony_ci        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
81cabdff1aSopenharmony_ci        return ret;
82cabdff1aSopenharmony_ci    }
83cabdff1aSopenharmony_ci    dst = pkt->data;
84cabdff1aSopenharmony_ci
85cabdff1aSopenharmony_ci    if (pic->format == AV_PIX_FMT_YUV422P10)
86cabdff1aSopenharmony_ci        v210_enc_10(avctx, dst, pic);
87cabdff1aSopenharmony_ci    else if(pic->format == AV_PIX_FMT_YUV422P)
88cabdff1aSopenharmony_ci        v210_enc_8(avctx, dst, pic);
89cabdff1aSopenharmony_ci
90cabdff1aSopenharmony_ci    side_data = av_frame_get_side_data(pic, AV_FRAME_DATA_A53_CC);
91cabdff1aSopenharmony_ci    if (side_data && side_data->size) {
92cabdff1aSopenharmony_ci        uint8_t *buf = av_packet_new_side_data(pkt, AV_PKT_DATA_A53_CC, side_data->size);
93cabdff1aSopenharmony_ci        if (!buf)
94cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
95cabdff1aSopenharmony_ci        memcpy(buf, side_data->data, side_data->size);
96cabdff1aSopenharmony_ci    }
97cabdff1aSopenharmony_ci
98cabdff1aSopenharmony_ci    side_data = av_frame_get_side_data(pic, AV_FRAME_DATA_AFD);
99cabdff1aSopenharmony_ci    if (side_data && side_data->size) {
100cabdff1aSopenharmony_ci        uint8_t *buf = av_packet_new_side_data(pkt, AV_PKT_DATA_AFD, side_data->size);
101cabdff1aSopenharmony_ci        if (!buf)
102cabdff1aSopenharmony_ci            return AVERROR(ENOMEM);
103cabdff1aSopenharmony_ci        memcpy(buf, side_data->data, side_data->size);
104cabdff1aSopenharmony_ci    }
105cabdff1aSopenharmony_ci
106cabdff1aSopenharmony_ci    *got_packet = 1;
107cabdff1aSopenharmony_ci    return 0;
108cabdff1aSopenharmony_ci}
109cabdff1aSopenharmony_ci
110cabdff1aSopenharmony_ciconst FFCodec ff_v210_encoder = {
111cabdff1aSopenharmony_ci    .p.name         = "v210",
112cabdff1aSopenharmony_ci    .p.long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
113cabdff1aSopenharmony_ci    .p.type         = AVMEDIA_TYPE_VIDEO,
114cabdff1aSopenharmony_ci    .p.id           = AV_CODEC_ID_V210,
115cabdff1aSopenharmony_ci    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
116cabdff1aSopenharmony_ci    .priv_data_size = sizeof(V210EncContext),
117cabdff1aSopenharmony_ci    .init           = encode_init,
118cabdff1aSopenharmony_ci    FF_CODEC_ENCODE_CB(encode_frame),
119cabdff1aSopenharmony_ci    .p.pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE },
120cabdff1aSopenharmony_ci    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
121cabdff1aSopenharmony_ci};
122