libavformat/img2.c
Go to the documentation of this file.
00001 /*
00002  * Image format
00003  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
00004  * Copyright (c) 2004 Michael Niedermayer
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 #include "libavutil/intreadwrite.h"
00024 #include "libavutil/avstring.h"
00025 #include "libavutil/log.h"
00026 #include "libavutil/opt.h"
00027 #include "libavutil/pixdesc.h"
00028 #include "libavutil/parseutils.h"
00029 #include "avformat.h"
00030 #include "avio_internal.h"
00031 #include "internal.h"
00032 
00033 typedef struct {
00034     const AVClass *class;  
00035     int img_first;
00036     int img_last;
00037     int img_number;
00038     int img_count;
00039     int is_pipe;
00040     int split_planes;  
00041     char path[1024];
00042     char *pixel_format;     
00043     char *video_size;       
00044     char *framerate;        
00045     int loop;
00046     int updatefirst;
00047 } VideoData;
00048 
00049 typedef struct {
00050     enum CodecID id;
00051     const char *str;
00052 } IdStrMap;
00053 
00054 static const IdStrMap img_tags[] = {
00055     { CODEC_ID_MJPEG     , "jpeg"},
00056     { CODEC_ID_MJPEG     , "jpg"},
00057     { CODEC_ID_LJPEG     , "ljpg"},
00058     { CODEC_ID_JPEGLS    , "jls"},
00059     { CODEC_ID_PNG       , "png"},
00060     { CODEC_ID_PNG       , "mng"},
00061     { CODEC_ID_PPM       , "ppm"},
00062     { CODEC_ID_PPM       , "pnm"},
00063     { CODEC_ID_PGM       , "pgm"},
00064     { CODEC_ID_PGMYUV    , "pgmyuv"},
00065     { CODEC_ID_PBM       , "pbm"},
00066     { CODEC_ID_PAM       , "pam"},
00067     { CODEC_ID_MPEG1VIDEO, "mpg1-img"},
00068     { CODEC_ID_MPEG2VIDEO, "mpg2-img"},
00069     { CODEC_ID_MPEG4     , "mpg4-img"},
00070     { CODEC_ID_FFV1      , "ffv1-img"},
00071     { CODEC_ID_RAWVIDEO  , "y"},
00072     { CODEC_ID_RAWVIDEO  , "raw"},
00073     { CODEC_ID_BMP       , "bmp"},
00074     { CODEC_ID_GIF       , "gif"},
00075     { CODEC_ID_TARGA     , "tga"},
00076     { CODEC_ID_TIFF      , "tiff"},
00077     { CODEC_ID_TIFF      , "tif"},
00078     { CODEC_ID_SGI       , "sgi"},
00079     { CODEC_ID_PTX       , "ptx"},
00080     { CODEC_ID_PCX       , "pcx"},
00081     { CODEC_ID_SUNRAST   , "sun"},
00082     { CODEC_ID_SUNRAST   , "ras"},
00083     { CODEC_ID_SUNRAST   , "rs"},
00084     { CODEC_ID_SUNRAST   , "im1"},
00085     { CODEC_ID_SUNRAST   , "im8"},
00086     { CODEC_ID_SUNRAST   , "im24"},
00087     { CODEC_ID_SUNRAST   , "sunras"},
00088     { CODEC_ID_JPEG2000  , "j2c"},
00089     { CODEC_ID_JPEG2000  , "j2k"},
00090     { CODEC_ID_JPEG2000  , "jp2"},
00091     { CODEC_ID_JPEG2000  , "jpc"},
00092     { CODEC_ID_DPX       , "dpx"},
00093     { CODEC_ID_PICTOR    , "pic"},
00094     { CODEC_ID_XWD       , "xwd"},
00095     { CODEC_ID_NONE      , NULL}
00096 };
00097 
00098 static const int sizes[][2] = {
00099     { 640, 480 },
00100     { 720, 480 },
00101     { 720, 576 },
00102     { 352, 288 },
00103     { 352, 240 },
00104     { 160, 128 },
00105     { 512, 384 },
00106     { 640, 352 },
00107     { 640, 240 },
00108 };
00109 
00110 static int infer_size(int *width_ptr, int *height_ptr, int size)
00111 {
00112     int i;
00113 
00114     for(i=0;i<FF_ARRAY_ELEMS(sizes);i++) {
00115         if ((sizes[i][0] * sizes[i][1]) == size) {
00116             *width_ptr = sizes[i][0];
00117             *height_ptr = sizes[i][1];
00118             return 0;
00119         }
00120     }
00121     return -1;
00122 }
00123 static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
00124 {
00125     str= strrchr(str, '.');
00126     if(!str) return CODEC_ID_NONE;
00127     str++;
00128 
00129     while (tags->id) {
00130         if (!av_strcasecmp(str, tags->str))
00131             return tags->id;
00132 
00133         tags++;
00134     }
00135     return CODEC_ID_NONE;
00136 }
00137 
00138 /* return -1 if no image found */
00139 static int find_image_range(int *pfirst_index, int *plast_index,
00140                             const char *path)
00141 {
00142     char buf[1024];
00143     int range, last_index, range1, first_index;
00144 
00145     /* find the first image */
00146     for(first_index = 0; first_index < 5; first_index++) {
00147         if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
00148             *pfirst_index =
00149             *plast_index = 1;
00150             if (avio_check(buf, AVIO_FLAG_READ) > 0)
00151                 return 0;
00152             return -1;
00153         }
00154         if (avio_check(buf, AVIO_FLAG_READ) > 0)
00155             break;
00156     }
00157     if (first_index == 5)
00158         goto fail;
00159 
00160     /* find the last image */
00161     last_index = first_index;
00162     for(;;) {
00163         range = 0;
00164         for(;;) {
00165             if (!range)
00166                 range1 = 1;
00167             else
00168                 range1 = 2 * range;
00169             if (av_get_frame_filename(buf, sizeof(buf), path,
00170                                       last_index + range1) < 0)
00171                 goto fail;
00172             if (avio_check(buf, AVIO_FLAG_READ) <= 0)
00173                 break;
00174             range = range1;
00175             /* just in case... */
00176             if (range >= (1 << 30))
00177                 goto fail;
00178         }
00179         /* we are sure than image last_index + range exists */
00180         if (!range)
00181             break;
00182         last_index += range;
00183     }
00184     *pfirst_index = first_index;
00185     *plast_index = last_index;
00186     return 0;
00187  fail:
00188     return -1;
00189 }
00190 
00191 
00192 static int read_probe(AVProbeData *p)
00193 {
00194     if (p->filename && av_str2id(img_tags, p->filename)) {
00195         if (av_filename_number_test(p->filename))
00196             return AVPROBE_SCORE_MAX;
00197         else
00198             return AVPROBE_SCORE_MAX/2;
00199     }
00200     return 0;
00201 }
00202 
00203 enum CodecID ff_guess_image2_codec(const char *filename)
00204 {
00205     return av_str2id(img_tags, filename);
00206 }
00207 
00208 #if FF_API_GUESS_IMG2_CODEC
00209 enum CodecID av_guess_image2_codec(const char *filename){
00210     return av_str2id(img_tags, filename);
00211 }
00212 #endif
00213 
00214 static int read_header(AVFormatContext *s1, AVFormatParameters *ap)
00215 {
00216     VideoData *s = s1->priv_data;
00217     int first_index, last_index, ret = 0;
00218     int width = 0, height = 0;
00219     AVStream *st;
00220     enum PixelFormat pix_fmt = PIX_FMT_NONE;
00221     AVRational framerate;
00222 
00223     s1->ctx_flags |= AVFMTCTX_NOHEADER;
00224 
00225     st = avformat_new_stream(s1, NULL);
00226     if (!st) {
00227         return AVERROR(ENOMEM);
00228     }
00229 
00230     if (s->pixel_format && (pix_fmt = av_get_pix_fmt(s->pixel_format)) == PIX_FMT_NONE) {
00231         av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", s->pixel_format);
00232         return AVERROR(EINVAL);
00233     }
00234     if (s->video_size && (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
00235         av_log(s, AV_LOG_ERROR, "Could not parse video size: %s.\n", s->video_size);
00236         return ret;
00237     }
00238     if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
00239         av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s->framerate);
00240         return ret;
00241     }
00242 
00243 #if FF_API_LOOP_INPUT
00244     if (s1->loop_input)
00245         s->loop = s1->loop_input;
00246 #endif
00247 
00248     av_strlcpy(s->path, s1->filename, sizeof(s->path));
00249     s->img_number = 0;
00250     s->img_count = 0;
00251 
00252     /* find format */
00253     if (s1->iformat->flags & AVFMT_NOFILE)
00254         s->is_pipe = 0;
00255     else{
00256         s->is_pipe = 1;
00257         st->need_parsing = AVSTREAM_PARSE_FULL;
00258     }
00259 
00260     avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
00261 
00262     if (width && height) {
00263         st->codec->width  = width;
00264         st->codec->height = height;
00265     }
00266 
00267     if (!s->is_pipe) {
00268         if (find_image_range(&first_index, &last_index, s->path) < 0)
00269             return AVERROR(ENOENT);
00270         s->img_first = first_index;
00271         s->img_last = last_index;
00272         s->img_number = first_index;
00273         /* compute duration */
00274         st->start_time = 0;
00275         st->duration = last_index - first_index + 1;
00276     }
00277 
00278     if(s1->video_codec_id){
00279         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00280         st->codec->codec_id = s1->video_codec_id;
00281     }else if(s1->audio_codec_id){
00282         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00283         st->codec->codec_id = s1->audio_codec_id;
00284     }else{
00285         const char *str= strrchr(s->path, '.');
00286         s->split_planes = str && !av_strcasecmp(str + 1, "y");
00287         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00288         st->codec->codec_id = av_str2id(img_tags, s->path);
00289         if (st->codec->codec_id == CODEC_ID_LJPEG)
00290             st->codec->codec_id = CODEC_ID_MJPEG;
00291     }
00292     if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != PIX_FMT_NONE)
00293         st->codec->pix_fmt = pix_fmt;
00294 
00295     return 0;
00296 }
00297 
00298 static int read_packet(AVFormatContext *s1, AVPacket *pkt)
00299 {
00300     VideoData *s = s1->priv_data;
00301     char filename[1024];
00302     int i;
00303     int size[3]={0}, ret[3]={0};
00304     AVIOContext *f[3];
00305     AVCodecContext *codec= s1->streams[0]->codec;
00306 
00307     if (!s->is_pipe) {
00308         /* loop over input */
00309         if (s->loop && s->img_number > s->img_last) {
00310             s->img_number = s->img_first;
00311         }
00312         if (s->img_number > s->img_last)
00313             return AVERROR_EOF;
00314         if (av_get_frame_filename(filename, sizeof(filename),
00315                                   s->path, s->img_number)<0 && s->img_number > 1)
00316             return AVERROR(EIO);
00317         for(i=0; i<3; i++){
00318             if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
00319                            &s1->interrupt_callback, NULL) < 0) {
00320                 if(i==1)
00321                     break;
00322                 av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename);
00323                 return AVERROR(EIO);
00324             }
00325             size[i]= avio_size(f[i]);
00326 
00327             if(!s->split_planes)
00328                 break;
00329             filename[ strlen(filename) - 1 ]= 'U' + i;
00330         }
00331 
00332         if(codec->codec_id == CODEC_ID_RAWVIDEO && !codec->width)
00333             infer_size(&codec->width, &codec->height, size[0]);
00334     } else {
00335         f[0] = s1->pb;
00336         if (url_feof(f[0]))
00337             return AVERROR(EIO);
00338         size[0]= 4096;
00339     }
00340 
00341     av_new_packet(pkt, size[0] + size[1] + size[2]);
00342     pkt->stream_index = 0;
00343     pkt->flags |= AV_PKT_FLAG_KEY;
00344 
00345     pkt->size= 0;
00346     for(i=0; i<3; i++){
00347         if(size[i]){
00348             ret[i]= avio_read(f[i], pkt->data + pkt->size, size[i]);
00349             if (!s->is_pipe)
00350                 avio_close(f[i]);
00351             if(ret[i]>0)
00352                 pkt->size += ret[i];
00353         }
00354     }
00355 
00356     if (ret[0] <= 0 || ret[1]<0 || ret[2]<0) {
00357         av_free_packet(pkt);
00358         return AVERROR(EIO); /* signal EOF */
00359     } else {
00360         s->img_count++;
00361         s->img_number++;
00362         return 0;
00363     }
00364 }
00365 
00366 #if CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER
00367 /******************************************************/
00368 /* image output */
00369 
00370 static int write_header(AVFormatContext *s)
00371 {
00372     VideoData *img = s->priv_data;
00373     const char *str;
00374 
00375     img->img_number = 1;
00376     av_strlcpy(img->path, s->filename, sizeof(img->path));
00377 
00378     /* find format */
00379     if (s->oformat->flags & AVFMT_NOFILE)
00380         img->is_pipe = 0;
00381     else
00382         img->is_pipe = 1;
00383 
00384     str = strrchr(img->path, '.');
00385     img->split_planes = str && !av_strcasecmp(str + 1, "y");
00386     return 0;
00387 }
00388 
00389 static int write_packet(AVFormatContext *s, AVPacket *pkt)
00390 {
00391     VideoData *img = s->priv_data;
00392     AVIOContext *pb[3];
00393     char filename[1024];
00394     AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
00395     int i;
00396 
00397     if (!img->is_pipe) {
00398         if (av_get_frame_filename(filename, sizeof(filename),
00399                                   img->path, img->img_number) < 0 && img->img_number>1 && !img->updatefirst) {
00400             av_log(s, AV_LOG_ERROR,
00401                    "Could not get frame filename number %d from pattern '%s'\n",
00402                    img->img_number, img->path);
00403             return AVERROR(EINVAL);
00404         }
00405         for(i=0; i<3; i++){
00406             if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE,
00407                            &s->interrupt_callback, NULL) < 0) {
00408                 av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename);
00409                 return AVERROR(EIO);
00410             }
00411 
00412             if(!img->split_planes)
00413                 break;
00414             filename[ strlen(filename) - 1 ]= 'U' + i;
00415         }
00416     } else {
00417         pb[0] = s->pb;
00418     }
00419 
00420     if(img->split_planes){
00421         int ysize = codec->width * codec->height;
00422         avio_write(pb[0], pkt->data        , ysize);
00423         avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
00424         avio_write(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2);
00425         avio_flush(pb[1]);
00426         avio_flush(pb[2]);
00427         avio_close(pb[1]);
00428         avio_close(pb[2]);
00429     }else{
00430         if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){
00431             AVStream *st = s->streams[0];
00432             if(st->codec->extradata_size > 8 &&
00433                AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){
00434                 if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c'))
00435                     goto error;
00436                 avio_wb32(pb[0], 12);
00437                 ffio_wfourcc(pb[0], "jP  ");
00438                 avio_wb32(pb[0], 0x0D0A870A); // signature
00439                 avio_wb32(pb[0], 20);
00440                 ffio_wfourcc(pb[0], "ftyp");
00441                 ffio_wfourcc(pb[0], "jp2 ");
00442                 avio_wb32(pb[0], 0);
00443                 ffio_wfourcc(pb[0], "jp2 ");
00444                 avio_write(pb[0], st->codec->extradata, st->codec->extradata_size);
00445             }else if(pkt->size >= 8 && AV_RB32(pkt->data) == 0xFF4FFF51){
00446                 //jpeg2000 codestream
00447             }else if(pkt->size < 8 ||
00448                      (!st->codec->extradata_size &&
00449                       AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature
00450             error:
00451                 av_log(s, AV_LOG_ERROR, "malformed JPEG 2000 codestream %X\n", AV_RB32(pkt->data));
00452                 return -1;
00453             }
00454         }
00455         avio_write(pb[0], pkt->data, pkt->size);
00456     }
00457     avio_flush(pb[0]);
00458     if (!img->is_pipe) {
00459         avio_close(pb[0]);
00460     }
00461 
00462     img->img_number++;
00463     return 0;
00464 }
00465 
00466 #endif /* CONFIG_IMAGE2_MUXER || CONFIG_IMAGE2PIPE_MUXER */
00467 
00468 #define OFFSET(x) offsetof(VideoData, x)
00469 #define DEC AV_OPT_FLAG_DECODING_PARAM
00470 #define ENC AV_OPT_FLAG_ENCODING_PARAM
00471 static const AVOption options[] = {
00472     { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00473     { "video_size",   "", OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
00474     { "framerate",    "", OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
00475     { "loop",         "", OFFSET(loop),         AV_OPT_TYPE_INT,    {.dbl = 0},    0, 1, DEC },
00476     { NULL },
00477 };
00478 
00479 static const AVOption muxoptions[] = {
00480     { "updatefirst",  "", OFFSET(updatefirst),  AV_OPT_TYPE_INT,    {.dbl = 0},    0, 1, ENC },
00481     { NULL },
00482 };
00483 
00484 /* input */
00485 #if CONFIG_IMAGE2_DEMUXER
00486 static const AVClass img2_class = {
00487     .class_name = "image2 demuxer",
00488     .item_name  = av_default_item_name,
00489     .option     = options,
00490     .version    = LIBAVUTIL_VERSION_INT,
00491 };
00492 AVInputFormat ff_image2_demuxer = {
00493     .name           = "image2",
00494     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
00495     .priv_data_size = sizeof(VideoData),
00496     .read_probe     = read_probe,
00497     .read_header    = read_header,
00498     .read_packet    = read_packet,
00499     .flags          = AVFMT_NOFILE,
00500     .priv_class     = &img2_class,
00501 };
00502 #endif
00503 #if CONFIG_IMAGE2PIPE_DEMUXER
00504 static const AVClass img2pipe_class = {
00505     .class_name = "image2pipe demuxer",
00506     .item_name  = av_default_item_name,
00507     .option     = options,
00508     .version    = LIBAVUTIL_VERSION_INT,
00509 };
00510 AVInputFormat ff_image2pipe_demuxer = {
00511     .name           = "image2pipe",
00512     .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
00513     .priv_data_size = sizeof(VideoData),
00514     .read_header    = read_header,
00515     .read_packet    = read_packet,
00516     .priv_class     = &img2pipe_class,
00517 };
00518 #endif
00519 
00520 /* output */
00521 #if CONFIG_IMAGE2_MUXER
00522 static const AVClass img2mux_class = {
00523     .class_name = "image2 muxer",
00524     .item_name  = av_default_item_name,
00525     .option     = muxoptions,
00526     .version    = LIBAVUTIL_VERSION_INT,
00527 };
00528 AVOutputFormat ff_image2_muxer = {
00529     .name           = "image2",
00530     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
00531     .extensions     = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
00532                       "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd",
00533     .priv_data_size = sizeof(VideoData),
00534     .video_codec    = CODEC_ID_MJPEG,
00535     .write_header   = write_header,
00536     .write_packet   = write_packet,
00537     .flags          = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE,
00538     .priv_class     = &img2mux_class,
00539 };
00540 #endif
00541 #if CONFIG_IMAGE2PIPE_MUXER
00542 AVOutputFormat ff_image2pipe_muxer = {
00543     .name           = "image2pipe",
00544     .long_name      = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
00545     .priv_data_size = sizeof(VideoData),
00546     .video_codec    = CODEC_ID_MJPEG,
00547     .write_header   = write_header,
00548     .write_packet   = write_packet,
00549     .flags          = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS
00550 };
00551 #endif