00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "avcodec.h"
00024 #include "libavutil/common.h"
00025 #include "libavutil/intreadwrite.h"
00026
00027 static av_cold int decode_init(AVCodecContext *avctx)
00028 {
00029 avctx->pix_fmt = PIX_FMT_YUV420P;
00030 avctx->coded_frame = avcodec_alloc_frame();
00031 if (!avctx->coded_frame)
00032 return AVERROR(ENOMEM);
00033
00034 return 0;
00035 }
00036
00037 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
00038 AVPacket *avpkt)
00039 {
00040 int h, w;
00041 AVFrame *pic = avctx->coded_frame;
00042 const uint8_t *src = avpkt->data;
00043 uint8_t *Y1, *Y2, *U, *V;
00044 int ret;
00045
00046 if (pic->data[0])
00047 avctx->release_buffer(avctx, pic);
00048
00049 if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
00050 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
00051 return AVERROR_INVALIDDATA;
00052 }
00053
00054 pic->reference = 0;
00055 if ((ret = avctx->get_buffer(avctx, pic)) < 0)
00056 return ret;
00057
00058 pic->pict_type = AV_PICTURE_TYPE_I;
00059 pic->key_frame = 1;
00060
00061 if (AV_RL32(src) != 0x01000002) {
00062 av_log_ask_for_sample(avctx, "Unknown frame header %X\n", AV_RL32(src));
00063 return AVERROR_PATCHWELCOME;
00064 }
00065 src += 16;
00066
00067 Y1 = pic->data[0];
00068 Y2 = pic->data[0] + pic->linesize[0];
00069 U = pic->data[1];
00070 V = pic->data[2];
00071 for (h = 0; h < avctx->height; h += 2) {
00072 for (w = 0; w < avctx->width; w += 2) {
00073 AV_WN16A(Y1 + w, AV_RN16A(src));
00074 AV_WN16A(Y2 + w, AV_RN16A(src + 2));
00075 U[w >> 1] = src[4] + 0x80;
00076 V[w >> 1] = src[5] + 0x80;
00077 src += 6;
00078 }
00079 Y1 += pic->linesize[0] << 1;
00080 Y2 += pic->linesize[0] << 1;
00081 U += pic->linesize[1];
00082 V += pic->linesize[2];
00083 }
00084
00085 *data_size = sizeof(AVFrame);
00086 *(AVFrame*)data = *pic;
00087
00088 return avpkt->size;
00089 }
00090
00091 static av_cold int decode_close(AVCodecContext *avctx)
00092 {
00093 AVFrame *pic = avctx->coded_frame;
00094 if (pic->data[0])
00095 avctx->release_buffer(avctx, pic);
00096 av_freep(&avctx->coded_frame);
00097
00098 return 0;
00099 }
00100
00101 AVCodec ff_dxtory_decoder = {
00102 .name = "dxtory",
00103 .long_name = NULL_IF_CONFIG_SMALL("Dxtory"),
00104 .type = AVMEDIA_TYPE_VIDEO,
00105 .id = AV_CODEC_ID_DXTORY,
00106 .init = decode_init,
00107 .close = decode_close,
00108 .decode = decode_frame,
00109 .capabilities = CODEC_CAP_DR1,
00110 };