static int image_probe(AVProbeData *p) { if (filename_number_test(p->filename) >= 0 && av_str2id(img_tags, p->filename)) return AVPROBE_SCORE_MAX; else return 0; }
static int read_probe(AVProbeData *p) { if (p->filename && av_str2id(img_tags, p->filename)) { if (av_filename_number_test(p->filename)) return AVPROBE_SCORE_MAX; else return AVPROBE_SCORE_MAX/2; } return 0; }
static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) { VideoData *s = s1->priv_data; int first_index, last_index; AVStream *st; s1->ctx_flags |= AVFMTCTX_NOHEADER; st = av_new_stream(s1, 0); if (!st) { av_free(s); return -ENOMEM; } 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) { 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; } st->codec.codec_type = CODEC_TYPE_VIDEO; st->codec.codec_id = av_str2id(img_tags, s->path); return 0; fail: av_free(s); return AVERROR_IO; }
static int img_write_packet(AVFormatContext *s, AVPacket *pkt) { VideoData *img = s->priv_data; ByteIOContext *pb[3]; char filename[1024]; AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; int i; if (!img->is_pipe) { if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number>1) { av_log(s, AV_LOG_ERROR, "Could not get frame filename from pattern\n"); return AVERROR(EIO); } for(i=0; i<3; i++){ if (url_fopen(&pb[i], filename, URL_WRONLY) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } if(codec->codec_id != CODEC_ID_RAWVIDEO) break; filename[ strlen(filename) - 1 ]= 'U' + i; } } else { pb[0] = s->pb; } if(codec->codec_id == CODEC_ID_RAWVIDEO){ int ysize = codec->width * codec->height; put_buffer(pb[0], pkt->data , ysize); put_buffer(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); put_buffer(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); put_flush_packet(pb[1]); put_flush_packet(pb[2]); url_fclose(pb[1]); url_fclose(pb[2]); }else{ if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){ AVStream *st = s->streams[0]; if(st->codec->extradata_size > 8 && AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){ if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c')) goto error; put_be32(pb[0], 12); put_tag (pb[0], "jP "); put_be32(pb[0], 0x0D0A870A); // signature put_be32(pb[0], 20); put_tag (pb[0], "ftyp"); put_tag (pb[0], "jp2 "); put_be32(pb[0], 0); put_tag (pb[0], "jp2 "); put_buffer(pb[0], st->codec->extradata, st->codec->extradata_size); }else if(pkt->size < 8 || (!st->codec->extradata_size && AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature error: av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n"); return -1; } } put_buffer(pb[0], pkt->data, pkt->size); } put_flush_packet(pb[0]); if (!img->is_pipe) { url_fclose(pb[0]); } img->img_number++; return 0; }
static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) { VideoData *s = s1->priv_data; int first_index, last_index; AVStream *st; s1->ctx_flags |= AVFMTCTX_NOHEADER; st = av_new_stream(s1, 0); if (!st) { return AVERROR(ENOMEM); } av_strlcpy(s->path, s1->filename, sizeof(s->path)); 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; st->need_parsing = AVSTREAM_PARSE_FULL; } if (!ap->time_base.num) { av_set_pts_info(st, 60, 1, 25); } else { av_set_pts_info(st, 60, ap->time_base.num, ap->time_base.den); } if(ap->width && ap->height){ st->codec->width = ap->width; st->codec->height= ap->height; } if (!s->is_pipe) { if (find_image_range(&first_index, &last_index, s->path) < 0) return AVERROR(ENOENT); s->img_first = first_index; s->img_last = last_index; s->img_number = first_index; /* compute duration */ st->start_time = 0; st->duration = last_index - first_index + 1; } if(s1->video_codec_id){ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = s1->video_codec_id; }else if(s1->audio_codec_id){ st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = s1->audio_codec_id; }else{ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = av_str2id(img_tags, s->path); } if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ap->pix_fmt != PIX_FMT_NONE) st->codec->pix_fmt = ap->pix_fmt; return 0; }
enum CodecID av_guess_image2_codec(const char *filename){ return av_str2id(img_tags, filename); }
static int write_packet(AVFormatContext *s, AVPacket *pkt) { VideoData *img = s->priv_data; AVIOContext *pb[3]; char filename[1024]; AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec; int i; if (!img->is_pipe) { if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 && img->img_number>1) { av_log(s, AV_LOG_ERROR, "Could not get frame filename number %d from pattern '%s'\n", img->img_number, img->path); return AVERROR(EINVAL); } for(i=0; i<3; i++){ if (avio_open(&pb[i], filename, AVIO_FLAG_WRITE) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } if(!img->split_planes) break; filename[ strlen(filename) - 1 ]= 'U' + i; } } else { pb[0] = s->pb; } if(img->split_planes){ int ysize = codec->width * codec->height; avio_write(pb[0], pkt->data , ysize); avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2); avio_write(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2); avio_flush(pb[1]); avio_flush(pb[2]); avio_close(pb[1]); avio_close(pb[2]); }else{ if(av_str2id(img_tags, s->filename) == CODEC_ID_JPEG2000){ AVStream *st = s->streams[0]; if(st->codec->extradata_size > 8 && AV_RL32(st->codec->extradata+4) == MKTAG('j','p','2','h')){ if(pkt->size < 8 || AV_RL32(pkt->data+4) != MKTAG('j','p','2','c')) goto error; avio_wb32(pb[0], 12); ffio_wfourcc(pb[0], "jP "); avio_wb32(pb[0], 0x0D0A870A); // signature avio_wb32(pb[0], 20); ffio_wfourcc(pb[0], "ftyp"); ffio_wfourcc(pb[0], "jp2 "); avio_wb32(pb[0], 0); ffio_wfourcc(pb[0], "jp2 "); avio_write(pb[0], st->codec->extradata, st->codec->extradata_size); }else if(pkt->size < 8 || (!st->codec->extradata_size && AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature error: av_log(s, AV_LOG_ERROR, "malformated jpeg2000 codestream\n"); return -1; } } avio_write(pb[0], pkt->data, pkt->size); } avio_flush(pb[0]); if (!img->is_pipe) { avio_close(pb[0]); } img->img_number++; return 0; }