FFmpeg
v210enc.c
Go to the documentation of this file.
1 /*
2  * V210 encoder
3  *
4  * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
5  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "avcodec.h"
25 #include "bytestream.h"
26 #include "internal.h"
27 #include "v210enc.h"
28 
29 #define CLIP(v) av_clip(v, 4, 1019)
30 #define CLIP8(v) av_clip(v, 1, 254)
31 
32 #define WRITE_PIXELS(a, b, c) \
33  do { \
34  val = CLIP(*a++); \
35  val |= (CLIP(*b++) << 10) | \
36  (CLIP(*c++) << 20); \
37  AV_WL32(dst, val); \
38  dst += 4; \
39  } while (0)
40 
41 #define WRITE_PIXELS8(a, b, c) \
42  do { \
43  val = (CLIP8(*a++) << 2); \
44  val |= (CLIP8(*b++) << 12) | \
45  (CLIP8(*c++) << 22); \
46  AV_WL32(dst, val); \
47  dst += 4; \
48  } while (0)
49 
50 static void v210_planar_pack_8_c(const uint8_t *y, const uint8_t *u,
51  const uint8_t *v, uint8_t *dst,
52  ptrdiff_t width)
53 {
54  uint32_t val;
55  int i;
56 
57  /* unroll this to match the assembly */
58  for (i = 0; i < width - 11; i += 12) {
59  WRITE_PIXELS8(u, y, v);
60  WRITE_PIXELS8(y, u, y);
61  WRITE_PIXELS8(v, y, u);
62  WRITE_PIXELS8(y, v, y);
63  WRITE_PIXELS8(u, y, v);
64  WRITE_PIXELS8(y, u, y);
65  WRITE_PIXELS8(v, y, u);
66  WRITE_PIXELS8(y, v, y);
67  }
68 }
69 
70 static void v210_planar_pack_10_c(const uint16_t *y, const uint16_t *u,
71  const uint16_t *v, uint8_t *dst,
72  ptrdiff_t width)
73 {
74  uint32_t val;
75  int i;
76 
77  for (i = 0; i < width - 5; i += 6) {
78  WRITE_PIXELS(u, y, v);
79  WRITE_PIXELS(y, u, y);
80  WRITE_PIXELS(v, y, u);
81  WRITE_PIXELS(y, v, y);
82  }
83 }
84 
86 {
87  s->pack_line_8 = v210_planar_pack_8_c;
88  s->pack_line_10 = v210_planar_pack_10_c;
89  s->sample_factor_8 = 1;
90  s->sample_factor_10 = 1;
91 
92  if (ARCH_X86)
94 }
95 
97 {
98  V210EncContext *s = avctx->priv_data;
99 
100  if (avctx->width & 1) {
101  av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
102  return AVERROR(EINVAL);
103  }
104 
105 #if FF_API_CODED_FRAME
109 #endif
110 
112 
113  avctx->bits_per_coded_sample = 20;
114  avctx->bit_rate = ff_guess_coded_bitrate(avctx) * 16 / 15;
115 
116  return 0;
117 }
118 
120  const AVFrame *pic, int *got_packet)
121 {
122  V210EncContext *s = avctx->priv_data;
123  int aligned_width = ((avctx->width + 47) / 48) * 48;
124  int stride = aligned_width * 8 / 3;
125  int line_padding = stride - ((avctx->width * 8 + 11) / 12) * 4;
126  AVFrameSideData *side_data;
127  int h, w, ret;
128  uint8_t *dst;
129 
130  ret = ff_alloc_packet2(avctx, pkt, avctx->height * stride, avctx->height * stride);
131  if (ret < 0) {
132  av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
133  return ret;
134  }
135  dst = pkt->data;
136 
137  if (pic->format == AV_PIX_FMT_YUV422P10) {
138  const uint16_t *y = (const uint16_t *)pic->data[0];
139  const uint16_t *u = (const uint16_t *)pic->data[1];
140  const uint16_t *v = (const uint16_t *)pic->data[2];
141 
142  const int sample_size = 6 * s->sample_factor_10;
143  const int sample_w = avctx->width / sample_size;
144 
145  for (h = 0; h < avctx->height; h++) {
146  uint32_t val;
147  w = sample_w * sample_size;
148  s->pack_line_10(y, u, v, dst, w);
149 
150  y += w;
151  u += w >> 1;
152  v += w >> 1;
153  dst += sample_w * 16 * s->sample_factor_10;
154 
155  for (; w < avctx->width - 5; w += 6) {
156  WRITE_PIXELS(u, y, v);
157  WRITE_PIXELS(y, u, y);
158  WRITE_PIXELS(v, y, u);
159  WRITE_PIXELS(y, v, y);
160  }
161  if (w < avctx->width - 1) {
162  WRITE_PIXELS(u, y, v);
163 
164  val = CLIP(*y++);
165  if (w == avctx->width - 2) {
166  AV_WL32(dst, val);
167  dst += 4;
168  }
169  }
170  if (w < avctx->width - 3) {
171  val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
172  AV_WL32(dst, val);
173  dst += 4;
174 
175  val = CLIP(*v++) | (CLIP(*y++) << 10);
176  AV_WL32(dst, val);
177  dst += 4;
178  }
179 
180  memset(dst, 0, line_padding);
181  dst += line_padding;
182  y += pic->linesize[0] / 2 - avctx->width;
183  u += pic->linesize[1] / 2 - avctx->width / 2;
184  v += pic->linesize[2] / 2 - avctx->width / 2;
185  }
186  } else if(pic->format == AV_PIX_FMT_YUV422P) {
187  const uint8_t *y = pic->data[0];
188  const uint8_t *u = pic->data[1];
189  const uint8_t *v = pic->data[2];
190 
191  const int sample_size = 12 * s->sample_factor_8;
192  const int sample_w = avctx->width / sample_size;
193 
194  for (h = 0; h < avctx->height; h++) {
195  uint32_t val;
196  w = sample_w * sample_size;
197  s->pack_line_8(y, u, v, dst, w);
198 
199  y += w;
200  u += w >> 1;
201  v += w >> 1;
202  dst += sample_w * 32 * s->sample_factor_8;
203 
204  for (; w < avctx->width - 5; w += 6) {
205  WRITE_PIXELS8(u, y, v);
206  WRITE_PIXELS8(y, u, y);
207  WRITE_PIXELS8(v, y, u);
208  WRITE_PIXELS8(y, v, y);
209  }
210  if (w < avctx->width - 1) {
211  WRITE_PIXELS8(u, y, v);
212 
213  val = CLIP8(*y++) << 2;
214  if (w == avctx->width - 2) {
215  AV_WL32(dst, val);
216  dst += 4;
217  }
218  }
219  if (w < avctx->width - 3) {
220  val |= (CLIP8(*u++) << 12) | (CLIP8(*y++) << 22);
221  AV_WL32(dst, val);
222  dst += 4;
223 
224  val = (CLIP8(*v++) << 2) | (CLIP8(*y++) << 12);
225  AV_WL32(dst, val);
226  dst += 4;
227  }
228  memset(dst, 0, line_padding);
229  dst += line_padding;
230 
231  y += pic->linesize[0] - avctx->width;
232  u += pic->linesize[1] - avctx->width / 2;
233  v += pic->linesize[2] - avctx->width / 2;
234  }
235  }
236 
238  if (side_data && side_data->size) {
240  if (!buf)
241  return AVERROR(ENOMEM);
242  memcpy(buf, side_data->data, side_data->size);
243  }
244 
245  side_data = av_frame_get_side_data(pic, AV_FRAME_DATA_AFD);
246  if (side_data && side_data->size) {
248  if (!buf)
249  return AVERROR(ENOMEM);
250  memcpy(buf, side_data->data, side_data->size);
251  }
252 
254  *got_packet = 1;
255  return 0;
256 }
257 
259  .name = "v210",
260  .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
261  .type = AVMEDIA_TYPE_VIDEO,
262  .id = AV_CODEC_ID_V210,
263  .priv_data_size = sizeof(V210EncContext),
264  .init = encode_init,
265  .encode2 = encode_frame,
267 };
ff_guess_coded_bitrate
int64_t ff_guess_coded_bitrate(AVCodecContext *avctx)
Get an estimated video bitrate based on frame size, frame rate and coded bits per pixel.
Definition: utils.c:2255
AVCodec
AVCodec.
Definition: avcodec.h:3481
FF_ENABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:85
stride
int stride
Definition: mace.c:144
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:734
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
AV_FRAME_DATA_A53_CC
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition: frame.h:58
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
CLIP
#define CLIP(v)
Definition: v210enc.c:29
AV_PKT_DATA_AFD
@ AV_PKT_DATA_AFD
Active Format Description data consisting of a single byte as specified in ETSI TS 101 154 using AVAc...
Definition: avcodec.h:1405
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
v210enc.h
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size)
Allocate new information of a packet.
Definition: avpacket.c:329
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1615
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
V210EncContext
Definition: v210enc.h:26
encode_frame
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet)
Definition: v210enc.c:119
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:388
ff_v210enc_init
av_cold void ff_v210enc_init(V210EncContext *s)
Definition: v210enc.c:85
AV_FRAME_DATA_AFD
@ AV_FRAME_DATA_AFD
Active Format Description data consisting of a single byte as specified in ETSI TS 101 154 using AVAc...
Definition: frame.h:89
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
AV_CODEC_ID_V210
@ AV_CODEC_ID_V210
Definition: avcodec.h:345
encode_init
static av_cold int encode_init(AVCodecContext *avctx)
Definition: v210enc.c:96
AVFrameSideData::data
uint8_t * data
Definition: frame.h:203
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:368
val
const char const char void * val
Definition: avisynth_c.h:863
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
AVCodecContext::bits_per_coded_sample
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2789
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AV_PKT_DATA_A53_CC
@ AV_PKT_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition: avcodec.h:1386
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
ff_v210enc_init_x86
void ff_v210enc_init_x86(V210EncContext *s)
Definition: v210enc_init.c:36
AVCodecContext::height
int height
Definition: avcodec.h:1738
avcodec.h
ret
ret
Definition: filter_design.txt:187
AVCodecContext::coded_frame
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:2815
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
WRITE_PIXELS8
#define WRITE_PIXELS8(a, b, c)
Definition: v210enc.c:41
FF_DISABLE_DEPRECATION_WARNINGS
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
ff_v210_encoder
AVCodec ff_v210_encoder
Definition: v210enc.c:258
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
v210_planar_pack_10_c
static void v210_planar_pack_10_c(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width)
Definition: v210enc.c:70
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:201
CLIP8
#define CLIP8(v)
Definition: v210enc.c:30
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
AVFrameSideData::size
int size
Definition: frame.h:204
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
bytestream.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
WRITE_PIXELS
#define WRITE_PIXELS(a, b, c)
Definition: v210enc.c:32
ff_alloc_packet2
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:32
v210_planar_pack_8_c
static void v210_planar_pack_8_c(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width)
Definition: v210enc.c:50