X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fimg.c;h=9c47d386266e20efb88d05c42e0fc2d2efe9fea0;hb=9ee91c2f53dbc7cc61e65805d57e0a805b5752d7;hp=0571c7ed5e30c3b9391fc79e02d6f957263c3a67;hpb=5c91a6755b6412c918e20ff4735ca30f38a12569;p=ffmpeg diff --git a/libavformat/img.c b/libavformat/img.c index 0571c7ed5e3..9c47d386266 100644 --- a/libavformat/img.c +++ b/libavformat/img.c @@ -16,28 +16,18 @@ * 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 #include "avformat.h" -#ifdef __MINGW32__ -# include -# define usleep(t) Sleep((t) / 1000) -#endif -#ifdef __BEOS__ -# ifndef usleep -# include -# define usleep(t) snooze((bigtime_t)(t)) -# endif -#endif -#if defined(CONFIG_OS2) -# include -# define usleep(t) _sleep2((t) / 1000) -#endif +/* XXX: this is a hack */ +int loop_input = 0; typedef struct { int width; int height; + int img_first; + int img_last; int img_number; + int img_count; int img_size; AVImageFormat *img_fmt; int pix_fmt; @@ -47,7 +37,55 @@ typedef struct { void *ptr; } VideoData; -int emulate_frame_rate; + +/* return -1 if no image found */ +static int find_image_range(int *pfirst_index, int *plast_index, + const char *path) +{ + char buf[1024]; + int range, last_index, range1, first_index; + + /* find the first image */ + for(first_index = 0; first_index < 5; first_index++) { + if (get_frame_filename(buf, sizeof(buf), path, first_index) < 0) + goto fail; + if (url_exist(buf)) + break; + } + if (first_index == 5) + goto fail; + + /* find the last image */ + last_index = first_index; + for(;;) { + range = 0; + for(;;) { + if (!range) + range1 = 1; + else + range1 = 2 * range; + if (get_frame_filename(buf, sizeof(buf), path, + last_index + range1) < 0) + goto fail; + if (!url_exist(buf)) + break; + range = range1; + /* just in case... */ + if (range >= (1 << 30)) + goto fail; + } + /* we are sure than image last_index + range exists */ + if (!range) + break; + last_index += range; + } + *pfirst_index = first_index; + *plast_index = last_index; + return 0; + fail: + return -1; +} + static int image_probe(AVProbeData *p) { @@ -71,7 +109,7 @@ static int read_header_alloc_cb(void *opaque, AVImageInfo *info) static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) { VideoData *s = s1->priv_data; - int i, ret; + int ret, first_index, last_index; char buf[1024]; ByteIOContext pb1, *f = &pb1; AVStream *st; @@ -87,23 +125,36 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) strcpy(s->path, s1->filename); s->img_number = 0; - + s->img_count = 0; + /* find format */ if (s1->iformat->flags & AVFMT_NOFILE) s->is_pipe = 0; else s->is_pipe = 1; + if (!ap || !ap->frame_rate) { + st->codec.frame_rate = 25; + st->codec.frame_rate_base = 1; + } else { + st->codec.frame_rate = ap->frame_rate; + st->codec.frame_rate_base = ap->frame_rate_base; + } + if (!s->is_pipe) { - /* try to find the first image */ - for(i=0;i<5;i++) { - if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) - goto fail; - if (url_fopen(f, buf, URL_RDONLY) >= 0) - break; - s->img_number++; - } - if (i == 5) + if (find_image_range(&first_index, &last_index, s->path) < 0) + goto fail; + s->img_first = first_index; + s->img_last = last_index; + s->img_number = first_index; + /* compute duration */ + st->start_time = 0; + st->duration = ((int64_t)AV_TIME_BASE * + (last_index - first_index + 1) * + st->codec.frame_rate_base) / st->codec.frame_rate; + if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) + goto fail; + if (url_fopen(f, buf, URL_RDONLY) < 0) goto fail; } else { f = &s1->pb; @@ -124,13 +175,8 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) st->codec.width = s->width; st->codec.height = s->height; st->codec.pix_fmt = s->pix_fmt; - s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height); + s->img_size = avpicture_get_size(s->pix_fmt, (s->width+15)&(~15), (s->height+15)&(~15)); - if (!ap || !ap->frame_rate) - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - else - st->codec.frame_rate = ap->frame_rate; - return 0; fail1: if (!s->is_pipe) @@ -147,7 +193,7 @@ static int read_packet_alloc_cb(void *opaque, AVImageInfo *info) if (info->width != s->width || info->height != s->height) return -1; - avpicture_fill(&info->pict, s->ptr, info->pix_fmt, info->width, info->height); + avpicture_fill(&info->pict, s->ptr, info->pix_fmt, (info->width+15)&(~15), (info->height+15)&(~15)); return 0; } @@ -157,25 +203,12 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) char filename[1024]; int ret; ByteIOContext f1, *f; - static INT64 first_frame; // BUG -> to context FIXME - - if (emulate_frame_rate) { - if (!first_frame) { - first_frame = av_gettime(); - } else { - INT64 pts; - INT64 nowus; - - nowus = av_gettime() - first_frame; - - pts = ((INT64)s->img_number * FRAME_RATE_BASE * 1000000) / (s1->streams[0]->codec.frame_rate); - - if (pts > nowus) - usleep(pts - nowus); - } - } if (!s->is_pipe) { + /* loop over input */ + if (loop_input && s->img_number > s->img_last) { + s->img_number = s->img_first; + } if (get_frame_filename(filename, sizeof(filename), s->path, s->img_number) < 0) return -EIO; @@ -201,7 +234,10 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) av_free_packet(pkt); return -EIO; /* signal EOF */ } else { - pkt->pts = ((INT64)s->img_number * s1->pts_den * FRAME_RATE_BASE) / (s1->streams[0]->codec.frame_rate * s1->pts_num); + /* XXX: computing this pts is not necessary as it is done in + the generic code too */ + pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec.frame_rate_base, s1->streams[0]->time_base.den, s1->streams[0]->codec.frame_rate) / s1->streams[0]->time_base.num; + s->img_count++; s->img_number++; return 0; } @@ -265,7 +301,7 @@ static int img_write_header(AVFormatContext *s) } static int img_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) + const uint8_t *buf, int size, int64_t pts) { VideoData *img = s->priv_data; AVStream *st = s->streams[stream_index]; @@ -293,6 +329,7 @@ static int img_write_packet(AVFormatContext *s, int stream_index, info.width = width; info.height = height; info.pix_fmt = st->codec.pix_fmt; + info.interleaved = 0; /* FIXME: there should be a way to set it right */ info.pict = *picture; ret = av_write_image(pb, img->img_fmt, &info); if (!img->is_pipe) { @@ -319,6 +356,7 @@ static AVInputFormat image_iformat = { img_read_packet, img_read_close, NULL, + NULL, AVFMT_NOFILE | AVFMT_NEEDNUMBER, };