Originally committed as revision 1439 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -12,9 +12,13 @@ OBJS= utils.o cutils.o allformats.o | |||||
| # mux and demuxes | # mux and demuxes | ||||
| OBJS+=mpeg.o mpegts.o ffm.o crc.o img.o raw.o rm.o asf.o \ | OBJS+=mpeg.o mpegts.o ffm.o crc.o img.o raw.o rm.o asf.o \ | ||||
| avienc.o avidec.o wav.o swf.o au.o gif.o mov.o jpeg.o dv.o framehook.o | |||||
| avienc.o avidec.o wav.o swf.o au.o gif.o mov.o jpeg.o dv.o \ | |||||
| yuv4mpeg.o | |||||
| # image formats | |||||
| OBJS+= pnm.o yuv.o | |||||
| # file I/O | # file I/O | ||||
| OBJS+= avio.o aviobuf.o file.o | OBJS+= avio.o aviobuf.o file.o | ||||
| OBJS+= framehook.o | |||||
| ifeq ($(BUILD_STRPTIME),yes) | ifeq ($(BUILD_STRPTIME),yes) | ||||
| OBJS+= strptime.o | OBJS+= strptime.o | ||||
| @@ -45,6 +45,8 @@ void av_register_all(void) | |||||
| mov_init(); | mov_init(); | ||||
| jpeg_init(); | jpeg_init(); | ||||
| dv_init(); | dv_init(); | ||||
| av_register_output_format(&yuv4mpegpipe_oformat); | |||||
| #ifdef CONFIG_VORBIS | #ifdef CONFIG_VORBIS | ||||
| ogg_init(); | ogg_init(); | ||||
| @@ -60,6 +62,14 @@ void av_register_all(void) | |||||
| audio_init(); | audio_init(); | ||||
| #endif | #endif | ||||
| /* image formats */ | |||||
| av_register_image_format(&pnm_image_format); | |||||
| av_register_image_format(&pbm_image_format); | |||||
| av_register_image_format(&pgm_image_format); | |||||
| av_register_image_format(&ppm_image_format); | |||||
| av_register_image_format(&pgmyuv_image_format); | |||||
| av_register_image_format(&yuv_image_format); | |||||
| /* file protocols */ | /* file protocols */ | ||||
| register_protocol(&file_protocol); | register_protocol(&file_protocol); | ||||
| register_protocol(&pipe_protocol); | register_protocol(&pipe_protocol); | ||||
| @@ -0,0 +1,285 @@ | |||||
| /* | |||||
| * PNM image format | |||||
| * Copyright (c) 2002, 2003 Fabrice Bellard. | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2 of the License, or (at your option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with this library; if not, write to the Free Software | |||||
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||||
| */ | |||||
| #include "avformat.h" | |||||
| static inline int pnm_space(int c) | |||||
| { | |||||
| return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); | |||||
| } | |||||
| static void pnm_get(ByteIOContext *f, char *str, int buf_size) | |||||
| { | |||||
| char *s; | |||||
| int c; | |||||
| /* skip spaces and comments */ | |||||
| for(;;) { | |||||
| c = url_fgetc(f); | |||||
| if (c == '#') { | |||||
| do { | |||||
| c = url_fgetc(f); | |||||
| } while (c != '\n' && c != URL_EOF); | |||||
| } else if (!pnm_space(c)) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| s = str; | |||||
| while (c != URL_EOF && !pnm_space(c)) { | |||||
| if ((s - str) < buf_size - 1) | |||||
| *s++ = c; | |||||
| c = url_fgetc(f); | |||||
| } | |||||
| *s = '\0'; | |||||
| } | |||||
| static int pnm_read1(ByteIOContext *f, | |||||
| int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque, | |||||
| int allow_yuv) | |||||
| { | |||||
| int i, n, linesize, h; | |||||
| char buf1[32]; | |||||
| unsigned char *ptr; | |||||
| AVImageInfo info1, *info = &info1; | |||||
| int ret; | |||||
| pnm_get(f, buf1, sizeof(buf1)); | |||||
| if (!strcmp(buf1, "P4")) { | |||||
| info->pix_fmt = PIX_FMT_MONOWHITE; | |||||
| } else if (!strcmp(buf1, "P5")) { | |||||
| if (allow_yuv) | |||||
| info->pix_fmt = PIX_FMT_YUV420P; | |||||
| else | |||||
| info->pix_fmt = PIX_FMT_GRAY8; | |||||
| } else if (!strcmp(buf1, "P6")) { | |||||
| info->pix_fmt = PIX_FMT_RGB24; | |||||
| } else { | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| pnm_get(f, buf1, sizeof(buf1)); | |||||
| info->width = atoi(buf1); | |||||
| if (info->width <= 0) | |||||
| return AVERROR_INVALIDDATA; | |||||
| pnm_get(f, buf1, sizeof(buf1)); | |||||
| info->height = atoi(buf1); | |||||
| if (info->height <= 0) | |||||
| return AVERROR_INVALIDDATA; | |||||
| if (info->pix_fmt != PIX_FMT_MONOWHITE) { | |||||
| pnm_get(f, buf1, sizeof(buf1)); | |||||
| } | |||||
| /* more check if YUV420 */ | |||||
| if (info->pix_fmt == PIX_FMT_YUV420P) { | |||||
| if ((info->width & 1) != 0) | |||||
| return AVERROR_INVALIDDATA; | |||||
| h = (info->height * 2); | |||||
| if ((h % 3) != 0) | |||||
| return AVERROR_INVALIDDATA; | |||||
| h /= 3; | |||||
| info->height = h; | |||||
| } | |||||
| ret = alloc_cb(opaque, info); | |||||
| if (ret) | |||||
| return ret; | |||||
| switch(info->pix_fmt) { | |||||
| default: | |||||
| return AVERROR_INVALIDDATA; | |||||
| case PIX_FMT_RGB24: | |||||
| n = info->width * 3; | |||||
| goto do_read; | |||||
| case PIX_FMT_GRAY8: | |||||
| n = info->width; | |||||
| goto do_read; | |||||
| case PIX_FMT_MONOWHITE: | |||||
| n = (info->width + 7) >> 3; | |||||
| do_read: | |||||
| ptr = info->pict.data[0]; | |||||
| linesize = info->pict.linesize[0]; | |||||
| for(i = 0; i < info->height; i++) { | |||||
| get_buffer(f, ptr, n); | |||||
| ptr += linesize; | |||||
| } | |||||
| break; | |||||
| case PIX_FMT_YUV420P: | |||||
| { | |||||
| unsigned char *ptr1, *ptr2; | |||||
| n = info->width; | |||||
| ptr = info->pict.data[0]; | |||||
| linesize = info->pict.linesize[0]; | |||||
| for(i = 0; i < info->height; i++) { | |||||
| get_buffer(f, ptr, n); | |||||
| ptr += linesize; | |||||
| } | |||||
| ptr1 = info->pict.data[1]; | |||||
| ptr2 = info->pict.data[2]; | |||||
| n >>= 1; | |||||
| h = info->height >> 1; | |||||
| for(i = 0; i < h; i++) { | |||||
| get_buffer(f, ptr1, n); | |||||
| get_buffer(f, ptr2, n); | |||||
| ptr1 += info->pict.linesize[1]; | |||||
| ptr2 += info->pict.linesize[2]; | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| static int pnm_read(ByteIOContext *f, | |||||
| int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) | |||||
| { | |||||
| return pnm_read1(f, alloc_cb, opaque, 0); | |||||
| } | |||||
| static int pgmyuv_read(ByteIOContext *f, | |||||
| int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) | |||||
| { | |||||
| return pnm_read1(f, alloc_cb, opaque, 1); | |||||
| } | |||||
| static int pnm_write(ByteIOContext *pb, AVImageInfo *info) | |||||
| { | |||||
| int i, h, h1, c, n, linesize; | |||||
| char buf[100]; | |||||
| UINT8 *ptr, *ptr1, *ptr2; | |||||
| h = info->height; | |||||
| h1 = h; | |||||
| switch(info->pix_fmt) { | |||||
| case PIX_FMT_MONOWHITE: | |||||
| c = '4'; | |||||
| n = (info->width + 7) >> 3; | |||||
| break; | |||||
| case PIX_FMT_GRAY8: | |||||
| c = '5'; | |||||
| n = info->width; | |||||
| break; | |||||
| case PIX_FMT_RGB24: | |||||
| c = '6'; | |||||
| n = info->width * 3; | |||||
| break; | |||||
| case PIX_FMT_YUV420P: | |||||
| c = '5'; | |||||
| n = info->width; | |||||
| h1 = (h * 3) / 2; | |||||
| break; | |||||
| default: | |||||
| return AVERROR_INVALIDDATA; | |||||
| } | |||||
| snprintf(buf, sizeof(buf), | |||||
| "P%c\n%d %d\n", | |||||
| c, info->width, h1); | |||||
| put_buffer(pb, buf, strlen(buf)); | |||||
| if (info->pix_fmt != PIX_FMT_MONOWHITE) { | |||||
| snprintf(buf, sizeof(buf), | |||||
| "%d\n", 255); | |||||
| put_buffer(pb, buf, strlen(buf)); | |||||
| } | |||||
| ptr = info->pict.data[0]; | |||||
| linesize = info->pict.linesize[0]; | |||||
| for(i=0;i<h;i++) { | |||||
| put_buffer(pb, ptr, n); | |||||
| ptr += linesize; | |||||
| } | |||||
| if (info->pix_fmt == PIX_FMT_YUV420P) { | |||||
| h >>= 1; | |||||
| n >>= 1; | |||||
| ptr1 = info->pict.data[1]; | |||||
| ptr2 = info->pict.data[2]; | |||||
| for(i=0;i<h;i++) { | |||||
| put_buffer(pb, ptr1, n); | |||||
| put_buffer(pb, ptr2, n); | |||||
| ptr1 += info->pict.linesize[1]; | |||||
| ptr2 += info->pict.linesize[2]; | |||||
| } | |||||
| } | |||||
| put_flush_packet(pb); | |||||
| return 0; | |||||
| } | |||||
| static int pnm_probe(AVProbeData *pd) | |||||
| { | |||||
| const char *p = pd->buf; | |||||
| if (pd->buf_size >= 8 && | |||||
| p[0] == 'P' && | |||||
| p[1] >= '4' && p[1] <= '6' && | |||||
| p[2] == '\n') | |||||
| return AVPROBE_SCORE_MAX; | |||||
| else | |||||
| return 0; | |||||
| } | |||||
| static int pgmyuv_probe(AVProbeData *pd) | |||||
| { | |||||
| if (match_ext(pd->filename, "pgmyuv")) | |||||
| return AVPROBE_SCORE_MAX; | |||||
| else | |||||
| return 0; | |||||
| } | |||||
| AVImageFormat pnm_image_format = { | |||||
| "pnm", | |||||
| NULL, | |||||
| pnm_probe, | |||||
| pnm_read, | |||||
| 0, | |||||
| NULL, | |||||
| }; | |||||
| AVImageFormat pbm_image_format = { | |||||
| "pbm", | |||||
| "pbm", | |||||
| NULL, | |||||
| NULL, | |||||
| (1 << PIX_FMT_MONOWHITE), | |||||
| pnm_write, | |||||
| }; | |||||
| AVImageFormat pgm_image_format = { | |||||
| "pgm", | |||||
| "pgm", | |||||
| NULL, | |||||
| NULL, | |||||
| (1 << PIX_FMT_GRAY8), | |||||
| pnm_write, | |||||
| }; | |||||
| AVImageFormat ppm_image_format = { | |||||
| "ppm", | |||||
| "ppm", | |||||
| NULL, | |||||
| NULL, | |||||
| (1 << PIX_FMT_RGB24), | |||||
| pnm_write, | |||||
| }; | |||||
| AVImageFormat pgmyuv_image_format = { | |||||
| "pgmyuv", | |||||
| NULL, | |||||
| pgmyuv_probe, | |||||
| pgmyuv_read, | |||||
| (1 << PIX_FMT_YUV420P), | |||||
| pnm_write, | |||||
| }; | |||||
| @@ -35,6 +35,7 @@ | |||||
| AVInputFormat *first_iformat; | AVInputFormat *first_iformat; | ||||
| AVOutputFormat *first_oformat; | AVOutputFormat *first_oformat; | ||||
| AVImageFormat *first_image_format; | |||||
| void av_register_input_format(AVInputFormat *format) | void av_register_input_format(AVInputFormat *format) | ||||
| { | { | ||||
| @@ -84,6 +85,11 @@ AVOutputFormat *guess_format(const char *short_name, const char *filename, | |||||
| AVOutputFormat *fmt, *fmt_found; | AVOutputFormat *fmt, *fmt_found; | ||||
| int score_max, score; | int score_max, score; | ||||
| /* specific test for image sequences */ | |||||
| if (!short_name && filename && filename_number_test(filename) >= 0) { | |||||
| return guess_format("image", NULL, NULL); | |||||
| } | |||||
| /* find the proper file type */ | /* find the proper file type */ | ||||
| fmt_found = NULL; | fmt_found = NULL; | ||||
| score_max = 0; | score_max = 0; | ||||
| @@ -326,8 +332,8 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | |||||
| fmt = av_probe_input_format(pd, 0); | fmt = av_probe_input_format(pd, 0); | ||||
| } | } | ||||
| /* if no file needed do not try to open one */ | |||||
| if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { | if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { | ||||
| /* if no file needed do not try to open one */ | |||||
| if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) { | if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) { | ||||
| err = AVERROR_IO; | err = AVERROR_IO; | ||||
| goto fail; | goto fail; | ||||
| @@ -365,6 +371,14 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | |||||
| ic->iformat = fmt; | ic->iformat = fmt; | ||||
| /* check filename in case of an image number is expected */ | |||||
| if (ic->iformat->flags & AVFMT_NEEDNUMBER) { | |||||
| if (filename_number_test(ic->filename) < 0) { | |||||
| err = AVERROR_NUMEXPECTED; | |||||
| goto fail1; | |||||
| } | |||||
| } | |||||
| /* allocate private data */ | /* allocate private data */ | ||||
| ic->priv_data = av_mallocz(fmt->priv_data_size); | ic->priv_data = av_mallocz(fmt->priv_data_size); | ||||
| if (!ic->priv_data) { | if (!ic->priv_data) { | ||||
| @@ -375,14 +389,6 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, | |||||
| /* default pts settings is MPEG like */ | /* default pts settings is MPEG like */ | ||||
| av_set_pts_info(ic, 33, 1, 90000); | av_set_pts_info(ic, 33, 1, 90000); | ||||
| /* check filename in case of an image number is expected */ | |||||
| if (ic->iformat->flags & AVFMT_NEEDNUMBER) { | |||||
| if (filename_number_test(ic->filename) < 0) { | |||||
| err = AVERROR_NUMEXPECTED; | |||||
| goto fail1; | |||||
| } | |||||
| } | |||||
| err = ic->iformat->read_header(ic, ap); | err = ic->iformat->read_header(ic, ap); | ||||
| if (err < 0) | if (err < 0) | ||||
| goto fail1; | goto fail1; | ||||
| @@ -707,6 +713,21 @@ AVStream *av_new_stream(AVFormatContext *s, int id) | |||||
| /************************************************************/ | /************************************************************/ | ||||
| /* output media file */ | /* output media file */ | ||||
| int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) | |||||
| { | |||||
| int ret; | |||||
| s->priv_data = av_mallocz(s->oformat->priv_data_size); | |||||
| if (!s->priv_data) | |||||
| return AVERROR_NOMEM; | |||||
| if (s->oformat->set_parameters) { | |||||
| ret = s->oformat->set_parameters(s, ap); | |||||
| if (ret < 0) | |||||
| return ret; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| /** | /** | ||||
| * allocate the stream private data and write the stream header to an | * allocate the stream private data and write the stream header to an | ||||
| * output media file | * output media file | ||||
| @@ -719,9 +740,6 @@ int av_write_header(AVFormatContext *s) | |||||
| int ret, i; | int ret, i; | ||||
| AVStream *st; | AVStream *st; | ||||
| s->priv_data = av_mallocz(s->oformat->priv_data_size); | |||||
| if (!s->priv_data) | |||||
| return AVERROR_NOMEM; | |||||
| /* default pts settings is MPEG like */ | /* default pts settings is MPEG like */ | ||||
| av_set_pts_info(s, 33, 1, 90000); | av_set_pts_info(s, 33, 1, 90000); | ||||
| ret = s->oformat->write_header(s); | ret = s->oformat->write_header(s); | ||||
| @@ -1291,3 +1309,88 @@ void av_frac_add(AVFrac *f, INT64 incr) | |||||
| } | } | ||||
| f->num = num; | f->num = num; | ||||
| } | } | ||||
| /** | |||||
| * register a new image format | |||||
| * @param img_fmt Image format descriptor | |||||
| */ | |||||
| void av_register_image_format(AVImageFormat *img_fmt) | |||||
| { | |||||
| AVImageFormat **p; | |||||
| p = &first_image_format; | |||||
| while (*p != NULL) p = &(*p)->next; | |||||
| *p = img_fmt; | |||||
| img_fmt->next = NULL; | |||||
| } | |||||
| /* guess image format */ | |||||
| AVImageFormat *av_probe_image_format(AVProbeData *pd) | |||||
| { | |||||
| AVImageFormat *fmt1, *fmt; | |||||
| int score, score_max; | |||||
| fmt = NULL; | |||||
| score_max = 0; | |||||
| for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { | |||||
| if (fmt1->img_probe) { | |||||
| score = fmt1->img_probe(pd); | |||||
| if (score > score_max) { | |||||
| score_max = score; | |||||
| fmt = fmt1; | |||||
| } | |||||
| } | |||||
| } | |||||
| return fmt; | |||||
| } | |||||
| AVImageFormat *guess_image_format(const char *filename) | |||||
| { | |||||
| AVImageFormat *fmt1; | |||||
| for(fmt1 = first_image_format; fmt1 != NULL; fmt1 = fmt1->next) { | |||||
| if (fmt1->extensions && match_ext(filename, fmt1->extensions)) | |||||
| return fmt1; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| /** | |||||
| * Read an image from a stream. | |||||
| * @param gb byte stream containing the image | |||||
| * @param fmt image format, NULL if probing is required | |||||
| */ | |||||
| int av_read_image(ByteIOContext *pb, const char *filename, | |||||
| AVImageFormat *fmt, | |||||
| int (*alloc_cb)(void *, AVImageInfo *info), void *opaque) | |||||
| { | |||||
| char buf[PROBE_BUF_SIZE]; | |||||
| AVProbeData probe_data, *pd = &probe_data; | |||||
| offset_t pos; | |||||
| int ret; | |||||
| if (!fmt) { | |||||
| pd->filename = (char *)filename; | |||||
| pd->buf = buf; | |||||
| pos = url_ftell(pb); | |||||
| pd->buf_size = get_buffer(pb, buf, PROBE_BUF_SIZE); | |||||
| url_fseek(pb, pos, SEEK_SET); | |||||
| fmt = av_probe_image_format(pd); | |||||
| } | |||||
| if (!fmt) | |||||
| return AVERROR_NOFMT; | |||||
| ret = fmt->img_read(pb, alloc_cb, opaque); | |||||
| return ret; | |||||
| } | |||||
| /** | |||||
| * Write an image to a stream. | |||||
| * @param pb byte stream for the image output | |||||
| * @param fmt image format | |||||
| * @param img image data and informations | |||||
| */ | |||||
| int av_write_image(ByteIOContext *pb, AVImageFormat *fmt, AVImageInfo *img) | |||||
| { | |||||
| return fmt->img_write(pb, img); | |||||
| } | |||||
| @@ -0,0 +1,158 @@ | |||||
| /* | |||||
| * .Y.U.V image format | |||||
| * Copyright (c) 2003 Fabrice Bellard. | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2 of the License, or (at your option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with this library; if not, write to the Free Software | |||||
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||||
| */ | |||||
| #include "avformat.h" | |||||
| static int sizes[][2] = { | |||||
| { 640, 480 }, | |||||
| { 720, 480 }, | |||||
| { 720, 576 }, | |||||
| { 352, 288 }, | |||||
| { 352, 240 }, | |||||
| { 160, 128 }, | |||||
| { 512, 384 }, | |||||
| { 640, 352 }, | |||||
| { 640, 240 }, | |||||
| }; | |||||
| static int infer_size(int *width_ptr, int *height_ptr, int size) | |||||
| { | |||||
| int i; | |||||
| for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) { | |||||
| if ((sizes[i][0] * sizes[i][1]) == size) { | |||||
| *width_ptr = sizes[i][0]; | |||||
| *height_ptr = sizes[i][1]; | |||||
| return 0; | |||||
| } | |||||
| } | |||||
| return -1; | |||||
| } | |||||
| static int yuv_read(ByteIOContext *f, | |||||
| int (*alloc_cb)(void *opaque, AVImageInfo *info), void *opaque) | |||||
| { | |||||
| ByteIOContext pb1, *pb = &pb1; | |||||
| int img_size, ret; | |||||
| char fname[1024], *p; | |||||
| int size; | |||||
| URLContext *h; | |||||
| AVImageInfo info1, *info = &info1; | |||||
| /* XXX: hack hack */ | |||||
| h = url_fileno(f); | |||||
| img_size = url_seek(h, 0, SEEK_END); | |||||
| url_get_filename(h, fname, sizeof(fname)); | |||||
| if (infer_size(&info->width, &info->height, img_size) < 0) { | |||||
| return -EIO; | |||||
| } | |||||
| info->pix_fmt = PIX_FMT_YUV420P; | |||||
| ret = alloc_cb(opaque, info); | |||||
| if (ret) | |||||
| return ret; | |||||
| size = info->width * info->height; | |||||
| p = strrchr(fname, '.'); | |||||
| if (!p || p[1] != 'Y') | |||||
| return -EIO; | |||||
| get_buffer(f, info->pict.data[0], size); | |||||
| p[1] = 'U'; | |||||
| if (url_fopen(pb, fname, URL_RDONLY) < 0) | |||||
| return -EIO; | |||||
| get_buffer(pb, info->pict.data[1], size / 4); | |||||
| url_fclose(pb); | |||||
| p[1] = 'V'; | |||||
| if (url_fopen(pb, fname, URL_RDONLY) < 0) | |||||
| return -EIO; | |||||
| get_buffer(pb, info->pict.data[2], size / 4); | |||||
| url_fclose(pb); | |||||
| return 0; | |||||
| } | |||||
| static int yuv_write(ByteIOContext *pb2, AVImageInfo *info) | |||||
| { | |||||
| ByteIOContext pb1, *pb; | |||||
| char fname[1024], *p; | |||||
| int i, j, width, height; | |||||
| UINT8 *ptr; | |||||
| URLContext *h; | |||||
| static const char *ext = "YUV"; | |||||
| /* XXX: hack hack */ | |||||
| h = url_fileno(pb2); | |||||
| url_get_filename(h, fname, sizeof(fname)); | |||||
| p = strrchr(fname, '.'); | |||||
| if (!p || p[1] != 'Y') | |||||
| return -EIO; | |||||
| width = info->width; | |||||
| height = info->height; | |||||
| for(i=0;i<3;i++) { | |||||
| if (i == 1) { | |||||
| width >>= 1; | |||||
| height >>= 1; | |||||
| } | |||||
| if (i >= 1) { | |||||
| pb = &pb1; | |||||
| p[1] = ext[i]; | |||||
| if (url_fopen(pb, fname, URL_WRONLY) < 0) | |||||
| return -EIO; | |||||
| } else { | |||||
| pb = pb2; | |||||
| } | |||||
| ptr = info->pict.data[i]; | |||||
| for(j=0;j<height;j++) { | |||||
| put_buffer(pb, ptr, width); | |||||
| ptr += info->pict.linesize[i]; | |||||
| } | |||||
| put_flush_packet(pb); | |||||
| if (i >= 1) { | |||||
| url_fclose(pb); | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| static int yuv_probe(AVProbeData *pd) | |||||
| { | |||||
| if (match_ext(pd->filename, "Y")) | |||||
| return AVPROBE_SCORE_MAX; | |||||
| else | |||||
| return 0; | |||||
| } | |||||
| AVImageFormat yuv_image_format = { | |||||
| "yuv", | |||||
| "Y", | |||||
| yuv_probe, | |||||
| yuv_read, | |||||
| (1 << PIX_FMT_YUV420P), | |||||
| yuv_write, | |||||
| }; | |||||