2 * Copyright (c) 2011 Derek Buitenhuis
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation;
9 * version 2 of the License.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA),
25 * 'ULH0' (YCbCr 4:2:0 BT.709), 'ULH2' (YCbCr 4:2:2 BT.709)
32 #include "libutvideo.h"
35 static av_cold
int utvideo_decode_init(AVCodecContext
*avctx
)
37 UtVideoContext
*utv
= (UtVideoContext
*)avctx
->priv_data
;
42 if (avctx
->extradata_size
!= 4*4) {
43 av_log(avctx
, AV_LOG_ERROR
, "Extradata size mismatch.\n");
48 info
.version
= AV_RL32(avctx
->extradata
);
49 info
.original_format
= AV_RL32(avctx
->extradata
+ 4);
50 info
.frameinfo_size
= AV_RL32(avctx
->extradata
+ 8);
51 info
.flags
= AV_RL32(avctx
->extradata
+ 12);
53 /* Pick format based on FOURCC */
54 switch (avctx
->codec_tag
) {
56 case MKTAG('U', 'L', 'H', '0'):
57 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
58 avctx
->colorspace
= AVCOL_SPC_BT709
;
61 case MKTAG('U', 'L', 'H', '2'):
62 avctx
->pix_fmt
= AV_PIX_FMT_YUYV422
;
63 avctx
->colorspace
= AVCOL_SPC_BT709
;
67 case MKTAG('U', 'L', 'Y', '0'):
68 avctx
->pix_fmt
= AV_PIX_FMT_YUV420P
;
71 case MKTAG('U', 'L', 'Y', '2'):
72 avctx
->pix_fmt
= AV_PIX_FMT_YUYV422
;
75 case MKTAG('U', 'L', 'R', 'G'):
76 avctx
->pix_fmt
= AV_PIX_FMT_BGR24
;
77 format
= UTVF_NFCC_BGR_BU
;
79 case MKTAG('U', 'L', 'R', 'A'):
80 avctx
->pix_fmt
= AV_PIX_FMT_RGB32
;
81 format
= UTVF_NFCC_BGRA_BU
;
84 av_log(avctx
, AV_LOG_ERROR
,
85 "Not a Ut Video FOURCC: %X\n", avctx
->codec_tag
);
89 /* Only allocate the buffer once */
90 utv
->buf_size
= avpicture_get_size(avctx
->pix_fmt
, avctx
->width
, avctx
->height
);
91 utv
->buffer
= (uint8_t *)av_malloc(utv
->buf_size
* sizeof(uint8_t));
93 if (utv
->buffer
== NULL
) {
94 av_log(avctx
, AV_LOG_ERROR
, "Unable to allocate output buffer.\n");
98 /* Allocate the output frame */
99 avctx
->coded_frame
= av_frame_alloc();
101 /* Ut Video only supports 8-bit */
102 avctx
->bits_per_raw_sample
= 8;
104 /* Is it interlaced? */
105 avctx
->coded_frame
->interlaced_frame
= info
.flags
& 0x800 ? 1 : 0;
107 /* Apparently Ut Video doesn't store this info... */
108 avctx
->coded_frame
->top_field_first
= 1;
111 * Create a Ut Video instance. Since the function wants
112 * an "interface name" string, pass it the name of the lib.
114 utv
->codec
= CCodec::CreateInstance(UNFCC(avctx
->codec_tag
), "libavcodec");
116 /* Initialize Decoding */
117 begin_ret
= utv
->codec
->DecodeBegin(format
, avctx
->width
, avctx
->height
,
118 CBGROSSWIDTH_WINDOWS
, &info
, sizeof(UtVideoExtra
));
120 /* Check to see if the decoder initlized properly */
121 if (begin_ret
!= 0) {
122 av_log(avctx
, AV_LOG_ERROR
,
123 "Could not initialize decoder: %d\n", begin_ret
);
130 static int utvideo_decode_frame(AVCodecContext
*avctx
, void *data
,
131 int *got_frame
, AVPacket
*avpkt
)
133 UtVideoContext
*utv
= (UtVideoContext
*)avctx
->priv_data
;
134 AVFrame
*pic
= avctx
->coded_frame
;
135 int w
= avctx
->width
, h
= avctx
->height
;
139 pic
->pict_type
= AV_PICTURE_TYPE_I
;
142 /* Decode the frame */
143 utv
->codec
->DecodeFrame(utv
->buffer
, avpkt
->data
, true);
145 /* Set the output data depending on the colorspace */
146 switch (avctx
->pix_fmt
) {
147 case AV_PIX_FMT_YUV420P
:
148 pic
->linesize
[0] = w
;
149 pic
->linesize
[1] = pic
->linesize
[2] = w
/ 2;
150 pic
->data
[0] = utv
->buffer
;
151 pic
->data
[2] = utv
->buffer
+ (w
* h
);
152 pic
->data
[1] = pic
->data
[2] + (w
* h
/ 4);
154 case AV_PIX_FMT_YUYV422
:
155 pic
->linesize
[0] = w
* 2;
156 pic
->data
[0] = utv
->buffer
;
158 case AV_PIX_FMT_BGR24
:
159 case AV_PIX_FMT_RGB32
:
160 /* Make the linesize negative, since Ut Video uses bottom-up BGR */
161 pic
->linesize
[0] = -1 * w
* (avctx
->pix_fmt
== AV_PIX_FMT_BGR24
? 3 : 4);
162 pic
->data
[0] = utv
->buffer
+ utv
->buf_size
+ pic
->linesize
[0];
167 av_frame_move_ref((AVFrame
*)data
, pic
);
172 static av_cold
int utvideo_decode_close(AVCodecContext
*avctx
)
174 UtVideoContext
*utv
= (UtVideoContext
*)avctx
->priv_data
;
177 av_frame_free(&avctx
->coded_frame
);
178 av_freep(&utv
->buffer
);
180 /* Finish decoding and clean up the instance */
181 utv
->codec
->DecodeEnd();
182 CCodec::DeleteInstance(utv
->codec
);
187 AVCodec ff_libutvideo_decoder
= {
189 NULL_IF_CONFIG_SMALL("Ut Video"),
193 NULL
, //supported_framerates
195 NULL
, //supported_samplerates
197 NULL
, //channel_layouts
201 sizeof(UtVideoContext
),
203 NULL
, //init_thread_copy
204 NULL
, //update_thread_context
206 NULL
, //init_static_data
210 utvideo_decode_frame
,
211 utvideo_decode_close
,