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 "internal.h"
00025
00026 static av_cold int avui_encode_init(AVCodecContext *avctx)
00027 {
00028 avctx->coded_frame = avcodec_alloc_frame();
00029
00030 if (avctx->width != 720 || avctx->height != 486 && avctx->height != 576) {
00031 av_log(avctx, AV_LOG_ERROR, "Only 720x486 and 720x576 are supported.\n");
00032 return AVERROR(EINVAL);
00033 }
00034 if (!avctx->coded_frame) {
00035 av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
00036 return AVERROR(ENOMEM);
00037 }
00038 if (!(avctx->extradata = av_mallocz(24 + FF_INPUT_BUFFER_PADDING_SIZE)))
00039 return AVERROR(ENOMEM);
00040 avctx->extradata_size = 24;
00041 memcpy(avctx->extradata, "\0\0\0\x18""APRGAPRG0001", 16);
00042 if (avctx->field_order > AV_FIELD_PROGRESSIVE) {
00043 avctx->extradata[19] = 2;
00044 } else {
00045 avctx->extradata[19] = 1;
00046 }
00047
00048
00049 return 0;
00050 }
00051
00052 static int avui_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00053 const AVFrame *pic, int *got_packet)
00054 {
00055 uint8_t *dst, *src = pic->data[0];
00056 int i, j, skip, ret, size, interlaced;
00057
00058 interlaced = avctx->field_order > AV_FIELD_PROGRESSIVE;
00059
00060 if (avctx->height == 486) {
00061 skip = 10;
00062 } else {
00063 skip = 16;
00064 }
00065 size = 2 * avctx->width * (avctx->height + skip) + 8 * interlaced;
00066 if ((ret = ff_alloc_packet2(avctx, pkt, size)) < 0)
00067 return ret;
00068 dst = pkt->data;
00069 if (!interlaced) {
00070 dst += avctx->width * skip;
00071 }
00072
00073 avctx->coded_frame->reference = 0;
00074 avctx->coded_frame->key_frame = 1;
00075 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
00076
00077 for (i = 0; i <= interlaced; i++) {
00078 if (interlaced && avctx->height == 486) {
00079 src = pic->data[0] + (1 - i) * pic->linesize[0];
00080 } else {
00081 src = pic->data[0] + i * pic->linesize[0];
00082 }
00083 dst += avctx->width * skip + 4 * i;
00084 for (j = 0; j < avctx->height; j += interlaced + 1) {
00085 memcpy(dst, src, avctx->width * 2);
00086 src += (interlaced + 1) * pic->linesize[0];
00087 dst += avctx->width * 2;
00088 }
00089 }
00090
00091 pkt->flags |= AV_PKT_FLAG_KEY;
00092 *got_packet = 1;
00093 return 0;
00094 }
00095
00096 static av_cold int avui_encode_close(AVCodecContext *avctx)
00097 {
00098 av_freep(&avctx->coded_frame);
00099
00100 return 0;
00101 }
00102
00103 AVCodec ff_avui_encoder = {
00104 .name = "avui",
00105 .type = AVMEDIA_TYPE_VIDEO,
00106 .id = AV_CODEC_ID_AVUI,
00107 .init = avui_encode_init,
00108 .encode2 = avui_encode_frame,
00109 .close = avui_encode_close,
00110 .capabilities = CODEC_CAP_EXPERIMENTAL,
00111 .pix_fmts = (const enum PixelFormat[]){ PIX_FMT_UYVY422, PIX_FMT_NONE },
00112 .long_name = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
00113 };