Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavformat/jpeg.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
| author | nenolod |
|---|---|
| date | Mon, 12 Mar 2007 11:18:54 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 807:0f9c8d4d3ac4 | 808:e8776388b02a |
|---|---|
| 1 /* | |
| 2 * JPEG image format | |
| 3 * Copyright (c) 2003 Fabrice Bellard. | |
| 4 * | |
| 5 * This file is part of FFmpeg. | |
| 6 * | |
| 7 * FFmpeg is free software; you can redistribute it and/or | |
| 8 * modify it under the terms of the GNU Lesser General Public | |
| 9 * License as published by the Free Software Foundation; either | |
| 10 * version 2.1 of the License, or (at your option) any later version. | |
| 11 * | |
| 12 * FFmpeg is distributed in the hope that it will be useful, | |
| 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 15 * Lesser General Public License for more details. | |
| 16 * | |
| 17 * You should have received a copy of the GNU Lesser General Public | |
| 18 * License along with FFmpeg; if not, write to the Free Software | |
| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 20 */ | |
| 21 #include "avformat.h" | |
| 22 | |
| 23 static int jpeg_probe(AVProbeData *pd) | |
| 24 { | |
| 25 if (pd->buf_size >= 64 && | |
| 26 pd->buf[0] == 0xff && pd->buf[1] == 0xd8 && pd->buf[2] == 0xff) | |
| 27 return AVPROBE_SCORE_MAX; | |
| 28 else | |
| 29 return 0; | |
| 30 } | |
| 31 | |
| 32 typedef struct JpegOpaque { | |
| 33 int (*alloc_cb)(void *opaque, AVImageInfo *info); | |
| 34 void *opaque; | |
| 35 int ret_code; | |
| 36 } JpegOpaque; | |
| 37 | |
| 38 /* called by the codec to allocate the image */ | |
| 39 static int jpeg_get_buffer(AVCodecContext *c, AVFrame *picture) | |
| 40 { | |
| 41 JpegOpaque *jctx = c->opaque; | |
| 42 AVImageInfo info1, *info = &info1; | |
| 43 int ret, i; | |
| 44 | |
| 45 info->width = c->width; | |
| 46 info->height = c->height; | |
| 47 switch(c->pix_fmt) { | |
| 48 case PIX_FMT_YUV420P: | |
| 49 info->pix_fmt = PIX_FMT_YUVJ420P; | |
| 50 break; | |
| 51 case PIX_FMT_YUV422P: | |
| 52 info->pix_fmt = PIX_FMT_YUVJ422P; | |
| 53 break; | |
| 54 case PIX_FMT_YUV444P: | |
| 55 info->pix_fmt = PIX_FMT_YUVJ444P; | |
| 56 break; | |
| 57 default: | |
| 58 return -1; | |
| 59 } | |
| 60 ret = jctx->alloc_cb(jctx->opaque, info); | |
| 61 if (ret) { | |
| 62 jctx->ret_code = ret; | |
| 63 return -1; | |
| 64 } else { | |
| 65 for(i=0;i<3;i++) { | |
| 66 picture->data[i] = info->pict.data[i]; | |
| 67 picture->linesize[i] = info->pict.linesize[i]; | |
| 68 } | |
| 69 return 0; | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 static void jpeg_img_copy(uint8_t *dst, int dst_wrap, | |
| 74 uint8_t *src, int src_wrap, | |
| 75 int width, int height) | |
| 76 { | |
| 77 for(;height > 0; height--) { | |
| 78 memcpy(dst, src, width); | |
| 79 dst += dst_wrap; | |
| 80 src += src_wrap; | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 /* XXX: libavcodec is broken for truncated jpegs! */ | |
| 85 #define IO_BUF_SIZE (1024*1024) | |
| 86 | |
| 87 static int jpeg_read(ByteIOContext *f, | |
| 88 int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) | |
| 89 { | |
| 90 AVCodecContext *c; | |
| 91 AVFrame *picture, picture1; | |
| 92 int len, size, got_picture, i; | |
| 93 uint8_t *inbuf_ptr, inbuf[IO_BUF_SIZE]; | |
| 94 JpegOpaque jctx; | |
| 95 | |
| 96 jctx.alloc_cb = alloc_cb; | |
| 97 jctx.opaque = opaque; | |
| 98 jctx.ret_code = -1; /* default return code is error */ | |
| 99 | |
| 100 c = avcodec_alloc_context(); | |
| 101 if (!c) | |
| 102 return -1; | |
| 103 picture= avcodec_alloc_frame(); | |
| 104 if (!picture) { | |
| 105 av_free(c); | |
| 106 return -1; | |
| 107 } | |
| 108 c->opaque = &jctx; | |
| 109 c->get_buffer = jpeg_get_buffer; | |
| 110 c->flags |= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */ | |
| 111 if (avcodec_open(c, &mjpeg_decoder) < 0) | |
| 112 goto fail1; | |
| 113 for(;;) { | |
| 114 size = get_buffer(f, inbuf, sizeof(inbuf)); | |
| 115 if (size == 0) | |
| 116 break; | |
| 117 inbuf_ptr = inbuf; | |
| 118 while (size > 0) { | |
| 119 len = avcodec_decode_video(c, &picture1, &got_picture, | |
| 120 inbuf_ptr, size); | |
| 121 if (len < 0) | |
| 122 goto fail; | |
| 123 if (got_picture) | |
| 124 goto the_end; | |
| 125 size -= len; | |
| 126 inbuf_ptr += len; | |
| 127 } | |
| 128 } | |
| 129 the_end: | |
| 130 /* XXX: currently, the mjpeg decoder does not use AVFrame, so we | |
| 131 must do it by hand */ | |
| 132 if (jpeg_get_buffer(c, picture) < 0) | |
| 133 goto fail; | |
| 134 for(i=0;i<3;i++) { | |
| 135 int w, h; | |
| 136 w = c->width; | |
| 137 h = c->height; | |
| 138 if (i >= 1) { | |
| 139 switch(c->pix_fmt) { | |
| 140 default: | |
| 141 case PIX_FMT_YUV420P: | |
| 142 w = (w + 1) >> 1; | |
| 143 h = (h + 1) >> 1; | |
| 144 break; | |
| 145 case PIX_FMT_YUV422P: | |
| 146 w = (w + 1) >> 1; | |
| 147 break; | |
| 148 case PIX_FMT_YUV444P: | |
| 149 break; | |
| 150 } | |
| 151 } | |
| 152 jpeg_img_copy(picture->data[i], picture->linesize[i], | |
| 153 picture1.data[i], picture1.linesize[i], | |
| 154 w, h); | |
| 155 } | |
| 156 jctx.ret_code = 0; | |
| 157 fail: | |
| 158 avcodec_close(c); | |
| 159 fail1: | |
| 160 av_free(picture); | |
| 161 av_free(c); | |
| 162 return jctx.ret_code; | |
| 163 } | |
| 164 | |
| 165 #if defined(CONFIG_MUXERS) && defined(CONFIG_MJPEG_ENCODER) | |
| 166 static int jpeg_write(ByteIOContext *pb, AVImageInfo *info) | |
| 167 { | |
| 168 AVCodecContext *c; | |
| 169 uint8_t *outbuf = NULL; | |
| 170 int outbuf_size, ret, size, i; | |
| 171 AVFrame *picture; | |
| 172 | |
| 173 ret = -1; | |
| 174 c = avcodec_alloc_context(); | |
| 175 if (!c) | |
| 176 return -1; | |
| 177 picture = avcodec_alloc_frame(); | |
| 178 if (!picture) | |
| 179 goto fail2; | |
| 180 c->width = info->width; | |
| 181 c->height = info->height; | |
| 182 /* XXX: currently move that to the codec ? */ | |
| 183 switch(info->pix_fmt) { | |
| 184 case PIX_FMT_YUVJ420P: | |
| 185 c->pix_fmt = PIX_FMT_YUV420P; | |
| 186 break; | |
| 187 case PIX_FMT_YUVJ422P: | |
| 188 c->pix_fmt = PIX_FMT_YUV422P; | |
| 189 break; | |
| 190 case PIX_FMT_YUVJ444P: | |
| 191 c->pix_fmt = PIX_FMT_YUV444P; | |
| 192 break; | |
| 193 default: | |
| 194 goto fail1; | |
| 195 } | |
| 196 for(i=0;i<3;i++) { | |
| 197 picture->data[i] = info->pict.data[i]; | |
| 198 picture->linesize[i] = info->pict.linesize[i]; | |
| 199 } | |
| 200 /* set the quality */ | |
| 201 picture->quality = 3; /* XXX: a parameter should be used */ | |
| 202 c->flags |= CODEC_FLAG_QSCALE; | |
| 203 | |
| 204 if (avcodec_open(c, &mjpeg_encoder) < 0) | |
| 205 goto fail1; | |
| 206 | |
| 207 /* XXX: needs to sort out that size problem */ | |
| 208 outbuf_size = 1000000; | |
| 209 outbuf = av_malloc(outbuf_size); | |
| 210 | |
| 211 size = avcodec_encode_video(c, outbuf, outbuf_size, picture); | |
| 212 if (size < 0) | |
| 213 goto fail; | |
| 214 put_buffer(pb, outbuf, size); | |
| 215 put_flush_packet(pb); | |
| 216 ret = 0; | |
| 217 | |
| 218 fail: | |
| 219 avcodec_close(c); | |
| 220 av_free(outbuf); | |
| 221 fail1: | |
| 222 av_free(picture); | |
| 223 fail2: | |
| 224 av_free(c); | |
| 225 return ret; | |
| 226 } | |
| 227 #endif //CONFIG_MUXERS | |
| 228 | |
| 229 AVImageFormat jpeg_image_format = { | |
| 230 "jpeg", | |
| 231 "jpg,jpeg", | |
| 232 jpeg_probe, | |
| 233 jpeg_read, | |
| 234 (1 << PIX_FMT_YUVJ420P) | (1 << PIX_FMT_YUVJ422P) | (1 << PIX_FMT_YUVJ444P), | |
| 235 #if defined(CONFIG_MUXERS) && defined(CONFIG_MJPEG_ENCODER) | |
| 236 jpeg_write, | |
| 237 #else | |
| 238 NULL, | |
| 239 #endif //CONFIG_MUXERS | |
| 240 }; |
