annotate ffmpeg/libavcodec/libutvideodec.cpp @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2011 Derek Buitenhuis
yading@10 3 *
yading@10 4 * This file is part of FFmpeg.
yading@10 5 *
yading@10 6 * FFmpeg is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU General Public
yading@10 8 * License as published by the Free Software Foundation;
yading@10 9 * version 2 of the License.
yading@10 10 *
yading@10 11 * FFmpeg is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU General Public
yading@10 17 * License along with FFmpeg; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 /**
yading@10 22 * @file
yading@10 23 * Known FOURCCs:
yading@10 24 * 'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
yading@10 25 */
yading@10 26
yading@10 27 extern "C" {
yading@10 28 #include "avcodec.h"
yading@10 29 }
yading@10 30
yading@10 31 #include "libutvideo.h"
yading@10 32 #include "get_bits.h"
yading@10 33
yading@10 34 static av_cold int utvideo_decode_init(AVCodecContext *avctx)
yading@10 35 {
yading@10 36 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
yading@10 37 UtVideoExtra info;
yading@10 38 int format;
yading@10 39 int begin_ret;
yading@10 40
yading@10 41 if (avctx->extradata_size != 4*4) {
yading@10 42 av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n");
yading@10 43 return -1;
yading@10 44 }
yading@10 45
yading@10 46 /* Read extradata */
yading@10 47 info.version = AV_RL32(avctx->extradata);
yading@10 48 info.original_format = AV_RL32(avctx->extradata + 4);
yading@10 49 info.frameinfo_size = AV_RL32(avctx->extradata + 8);
yading@10 50 info.flags = AV_RL32(avctx->extradata + 12);
yading@10 51
yading@10 52 /* Pick format based on FOURCC */
yading@10 53 switch (avctx->codec_tag) {
yading@10 54 case MKTAG('U', 'L', 'Y', '0'):
yading@10 55 avctx->pix_fmt = AV_PIX_FMT_YUV420P;
yading@10 56 format = UTVF_YV12;
yading@10 57 break;
yading@10 58 case MKTAG('U', 'L', 'Y', '2'):
yading@10 59 avctx->pix_fmt = AV_PIX_FMT_YUYV422;
yading@10 60 format = UTVF_YUY2;
yading@10 61 break;
yading@10 62 case MKTAG('U', 'L', 'R', 'G'):
yading@10 63 avctx->pix_fmt = AV_PIX_FMT_BGR24;
yading@10 64 format = UTVF_NFCC_BGR_BU;
yading@10 65 break;
yading@10 66 case MKTAG('U', 'L', 'R', 'A'):
yading@10 67 avctx->pix_fmt = AV_PIX_FMT_RGB32;
yading@10 68 format = UTVF_NFCC_BGRA_BU;
yading@10 69 break;
yading@10 70 default:
yading@10 71 av_log(avctx, AV_LOG_ERROR,
yading@10 72 "Not a Ut Video FOURCC: %X\n", avctx->codec_tag);
yading@10 73 return -1;
yading@10 74 }
yading@10 75
yading@10 76 /* Only allocate the buffer once */
yading@10 77 utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
yading@10 78 utv->buffer = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t));
yading@10 79
yading@10 80 if (utv->buffer == NULL) {
yading@10 81 av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n");
yading@10 82 return -1;
yading@10 83 }
yading@10 84
yading@10 85 /* Allocate the output frame */
yading@10 86 avctx->coded_frame = avcodec_alloc_frame();
yading@10 87
yading@10 88 /* Ut Video only supports 8-bit */
yading@10 89 avctx->bits_per_raw_sample = 8;
yading@10 90
yading@10 91 /* Is it interlaced? */
yading@10 92 avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0;
yading@10 93
yading@10 94 /* Apparently Ut Video doesn't store this info... */
yading@10 95 avctx->coded_frame->top_field_first = 1;
yading@10 96
yading@10 97 /*
yading@10 98 * Create a Ut Video instance. Since the function wants
yading@10 99 * an "interface name" string, pass it the name of the lib.
yading@10 100 */
yading@10 101 utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec");
yading@10 102
yading@10 103 /* Initialize Decoding */
yading@10 104 begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height,
yading@10 105 CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra));
yading@10 106
yading@10 107 /* Check to see if the decoder initlized properly */
yading@10 108 if (begin_ret != 0) {
yading@10 109 av_log(avctx, AV_LOG_ERROR,
yading@10 110 "Could not initialize decoder: %d\n", begin_ret);
yading@10 111 return -1;
yading@10 112 }
yading@10 113
yading@10 114 return 0;
yading@10 115 }
yading@10 116
yading@10 117 static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
yading@10 118 int *got_frame, AVPacket *avpkt)
yading@10 119 {
yading@10 120 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
yading@10 121 AVFrame *pic = avctx->coded_frame;
yading@10 122 int w = avctx->width, h = avctx->height;
yading@10 123
yading@10 124 /* Set flags */
yading@10 125 pic->reference = 0;
yading@10 126 pic->pict_type = AV_PICTURE_TYPE_I;
yading@10 127 pic->key_frame = 1;
yading@10 128
yading@10 129 /* Decode the frame */
yading@10 130 utv->codec->DecodeFrame(utv->buffer, avpkt->data, true);
yading@10 131
yading@10 132 /* Set the output data depending on the colorspace */
yading@10 133 switch (avctx->pix_fmt) {
yading@10 134 case AV_PIX_FMT_YUV420P:
yading@10 135 pic->linesize[0] = w;
yading@10 136 pic->linesize[1] = pic->linesize[2] = w / 2;
yading@10 137 pic->data[0] = utv->buffer;
yading@10 138 pic->data[2] = utv->buffer + (w * h);
yading@10 139 pic->data[1] = pic->data[2] + (w * h / 4);
yading@10 140 break;
yading@10 141 case AV_PIX_FMT_YUYV422:
yading@10 142 pic->linesize[0] = w * 2;
yading@10 143 pic->data[0] = utv->buffer;
yading@10 144 break;
yading@10 145 case AV_PIX_FMT_BGR24:
yading@10 146 case AV_PIX_FMT_RGB32:
yading@10 147 /* Make the linesize negative, since Ut Video uses bottom-up BGR */
yading@10 148 pic->linesize[0] = -1 * w * (avctx->pix_fmt == AV_PIX_FMT_BGR24 ? 3 : 4);
yading@10 149 pic->data[0] = utv->buffer + utv->buf_size + pic->linesize[0];
yading@10 150 break;
yading@10 151 }
yading@10 152
yading@10 153 *got_frame = 1;
yading@10 154 *(AVFrame *)data = *pic;
yading@10 155
yading@10 156 return avpkt->size;
yading@10 157 }
yading@10 158
yading@10 159 static av_cold int utvideo_decode_close(AVCodecContext *avctx)
yading@10 160 {
yading@10 161 UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
yading@10 162
yading@10 163 /* Free output */
yading@10 164 av_freep(&avctx->coded_frame);
yading@10 165 av_freep(&utv->buffer);
yading@10 166
yading@10 167 /* Finish decoding and clean up the instance */
yading@10 168 utv->codec->DecodeEnd();
yading@10 169 CCodec::DeleteInstance(utv->codec);
yading@10 170
yading@10 171 return 0;
yading@10 172 }
yading@10 173
yading@10 174 AVCodec ff_libutvideo_decoder = {
yading@10 175 "libutvideo",
yading@10 176 NULL_IF_CONFIG_SMALL("Ut Video"),
yading@10 177 AVMEDIA_TYPE_VIDEO,
yading@10 178 AV_CODEC_ID_UTVIDEO,
yading@10 179 0, //capabilities
yading@10 180 NULL, //supported_framerates
yading@10 181 NULL, //pix_fmts
yading@10 182 NULL, //supported_samplerates
yading@10 183 NULL, //sample_fmts
yading@10 184 NULL, //channel_layouts
yading@10 185 0, //max_lowres
yading@10 186 NULL, //priv_class
yading@10 187 NULL, //profiles
yading@10 188 sizeof(UtVideoContext),
yading@10 189 NULL, //next
yading@10 190 NULL, //init_thread_copy
yading@10 191 NULL, //update_thread_context
yading@10 192 NULL, //defaults
yading@10 193 NULL, //init_static_data
yading@10 194 utvideo_decode_init,
yading@10 195 NULL, //encode
yading@10 196 NULL, //encode2
yading@10 197 utvideo_decode_frame,
yading@10 198 utvideo_decode_close,
yading@10 199 };