00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "libavutil/imgutils.h"
00024 #include "avcodec.h"
00025 #include "internal.h"
00026
00027 typedef struct DPXContext {
00028 AVFrame picture;
00029 int big_endian;
00030 int bits_per_component;
00031 int descriptor;
00032 } DPXContext;
00033
00034 static av_cold int encode_init(AVCodecContext *avctx)
00035 {
00036 DPXContext *s = avctx->priv_data;
00037
00038 avctx->coded_frame = &s->picture;
00039 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00040 avctx->coded_frame->key_frame = 1;
00041
00042 s->big_endian = 1;
00043 s->bits_per_component = 8;
00044 s->descriptor = 50;
00045
00046 switch (avctx->pix_fmt) {
00047 case PIX_FMT_RGB24:
00048 break;
00049 case PIX_FMT_RGBA:
00050 s->descriptor = 51;
00051 break;
00052 case PIX_FMT_RGB48LE:
00053 s->big_endian = 0;
00054 case PIX_FMT_RGB48BE:
00055 s->bits_per_component = avctx->bits_per_raw_sample ? avctx->bits_per_raw_sample : 16;
00056 break;
00057 case PIX_FMT_RGBA64LE:
00058 s->big_endian = 0;
00059 case PIX_FMT_RGBA64BE:
00060 s->descriptor = 51;
00061 s->bits_per_component = 16;
00062 break;
00063 default:
00064 av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
00065 return -1;
00066 }
00067
00068 return 0;
00069 }
00070
00071 #define write16(p, value) \
00072 do { \
00073 if (s->big_endian) AV_WB16(p, value); \
00074 else AV_WL16(p, value); \
00075 } while(0)
00076
00077 #define write32(p, value) \
00078 do { \
00079 if (s->big_endian) AV_WB32(p, value); \
00080 else AV_WL32(p, value); \
00081 } while(0)
00082
00083 static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst)
00084 {
00085 DPXContext *s = avctx->priv_data;
00086 const uint8_t *src = pic->data[0];
00087 int x, y;
00088
00089 for (y = 0; y < avctx->height; y++) {
00090 for (x = 0; x < avctx->width; x++) {
00091 int value;
00092 if ((avctx->pix_fmt & 1)) {
00093 value = ((AV_RB16(src + 6*x + 4) & 0xFFC0) >> 4)
00094 | ((AV_RB16(src + 6*x + 2) & 0xFFC0) << 6)
00095 | ((AV_RB16(src + 6*x + 0) & 0xFFC0) << 16);
00096 } else {
00097 value = ((AV_RL16(src + 6*x + 4) & 0xFFC0) >> 4)
00098 | ((AV_RL16(src + 6*x + 2) & 0xFFC0) << 6)
00099 | ((AV_RL16(src + 6*x + 0) & 0xFFC0) << 16);
00100 }
00101 write32(dst, value);
00102 dst += 4;
00103 }
00104 src += pic->linesize[0];
00105 }
00106 }
00107
00108 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00109 const AVFrame *frame, int *got_packet)
00110 {
00111 DPXContext *s = avctx->priv_data;
00112 int size, ret;
00113 uint8_t *buf;
00114
00115 #define HEADER_SIZE 1664
00116 if (s->bits_per_component == 10)
00117 size = avctx->height * avctx->width * 4;
00118 else
00119 size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
00120 if ((ret = ff_alloc_packet2(avctx, pkt, size + HEADER_SIZE)) < 0)
00121 return ret;
00122 buf = pkt->data;
00123
00124 memset(buf, 0, HEADER_SIZE);
00125
00126
00127 write32(buf, MKBETAG('S','D','P','X'));
00128 write32(buf + 4, HEADER_SIZE);
00129 memcpy (buf + 8, "V1.0", 4);
00130 write32(buf + 20, 1);
00131 write32(buf + 24, HEADER_SIZE);
00132 if (!(avctx->flags & CODEC_FLAG_BITEXACT))
00133 memcpy (buf + 160, LIBAVCODEC_IDENT, FFMIN(sizeof(LIBAVCODEC_IDENT), 100));
00134 write32(buf + 660, 0xFFFFFFFF);
00135
00136
00137 write16(buf + 768, 0);
00138 write16(buf + 770, 1);
00139 write32(buf + 772, avctx->width);
00140 write32(buf + 776, avctx->height);
00141 buf[800] = s->descriptor;
00142 buf[801] = 2;
00143 buf[802] = 2;
00144 buf[803] = s->bits_per_component;
00145 write16(buf + 804, s->bits_per_component == 10 ? 1 : 0);
00146
00147
00148 write32(buf + 1628, avctx->sample_aspect_ratio.num);
00149 write32(buf + 1632, avctx->sample_aspect_ratio.den);
00150
00151 switch(s->bits_per_component) {
00152 case 8:
00153 case 16:
00154 size = avpicture_layout((const AVPicture*)frame, avctx->pix_fmt,
00155 avctx->width, avctx->height,
00156 buf + HEADER_SIZE, pkt->size - HEADER_SIZE);
00157 if (size < 0)
00158 return size;
00159 break;
00160 case 10:
00161 encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
00162 break;
00163 default:
00164 av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", s->bits_per_component);
00165 return -1;
00166 }
00167
00168 size += HEADER_SIZE;
00169
00170 write32(buf + 16, size);
00171
00172 pkt->flags |= AV_PKT_FLAG_KEY;
00173 *got_packet = 1;
00174
00175 return 0;
00176 }
00177
00178 AVCodec ff_dpx_encoder = {
00179 .name = "dpx",
00180 .type = AVMEDIA_TYPE_VIDEO,
00181 .id = CODEC_ID_DPX,
00182 .priv_data_size = sizeof(DPXContext),
00183 .init = encode_init,
00184 .encode2 = encode_frame,
00185 .pix_fmts = (const enum PixelFormat[]){
00186 PIX_FMT_RGB24,
00187 PIX_FMT_RGBA,
00188 PIX_FMT_RGB48LE,
00189 PIX_FMT_RGB48BE,
00190 PIX_FMT_RGBA64LE,
00191 PIX_FMT_RGBA64BE,
00192 PIX_FMT_NONE},
00193 .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
00194 };