static int pmp_probe(AVProbeData *p) { if (AV_RN32(p->buf) == AV_RN32("pmpm") && AV_RL32(p->buf + 4) == 1) return AVPROBE_SCORE_MAX; return 0; }
static int dpx_probe(AVProbeData *p) { const uint8_t *b = p->buf; if (AV_RN32(b) == AV_RN32("SDPX") || AV_RN32(b) == AV_RN32("XPDS")) return AVPROBE_SCORE_EXTENSION + 1; return 0; }
// http://multimedia.cx/ingenient.txt static int ingenient_probe(AVProbeData *p) { if ( AV_RN32(p->buf) != AV_RN32("MJPG") || p->buf_size < 50 || AV_RB16(p->buf + 48) != 0xffd8) return 0; return AVPROBE_SCORE_MAX * 3 / 4; }
static int dpx_probe(AVProbeData *p) { const uint8_t *b = p->buf; int w, h; int is_big = (AV_RN32(b) == AV_RN32("SDPX")); if (p->buf_size < 0x304+8) return 0; w = is_big ? AV_RB32(p->buf + 0x304) : AV_RL32(p->buf + 0x304); h = is_big ? AV_RB32(p->buf + 0x308) : AV_RL32(p->buf + 0x308); if (w <= 0 || h <= 0) return 0; if (is_big || AV_RN32(b) == AV_RN32("XPDS")) return AVPROBE_SCORE_EXTENSION + 1; return 0; }
static void clear_image(DrawGraphContext *s, AVFrame *out, AVFilterLink *outlink) { int i, j; int bg = AV_RN32(s->bg); for (i = 0; i < out->height; i++) for (j = 0; j < out->width; j++) AV_WN32(out->data[0] + i * out->linesize[0] + j * 4, bg); }
static int bmp_probe(AVProbeData *p) { const uint8_t *b = p->buf; int ihsize; if (AV_RB16(b) != 0x424d) return 0; ihsize = AV_RL32(b+14); if (ihsize < 12 || ihsize > 255) return 0; if (!AV_RN32(b + 6)) { return AVPROBE_SCORE_EXTENSION + 1; } return AVPROBE_SCORE_EXTENSION / 4; }
static int bmp_probe(AVProbeData *p) { const uint8_t *b = p->buf; int ihsize; if (AV_RB16(b) != 0x424d) return 0; ihsize = AV_RL32(b+14); if (ihsize < 12 || ihsize > 255) return 0; if (!AV_RN32(b + 6)) { return AVPROBE_SCORE_EXTENSION - 1; // lower than extension as bmp pipe has bugs } else { return AVPROBE_SCORE_EXTENSION / 4; } return 0; }
static int wv_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; WVContext *wc = s->priv_data; AVStream *st; int ret; wc->block_parsed = 0; for(;;) { if ((ret = wv_read_block_header(s, pb, 0)) < 0) return ret; if(!AV_RN32(wc->extra)) avio_skip(pb, wc->blksize - 24); else break; } /* now we are ready: build format streams */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_WAVPACK; st->codec->channels = wc->chan; st->codec->channel_layout = wc->chmask; st->codec->sample_rate = wc->rate; st->codec->bits_per_coded_sample = wc->bpp; avpriv_set_pts_info(st, 64, 1, wc->rate); st->start_time = 0; st->duration = wc->samples; if(s->pb->seekable) { int64_t cur = avio_tell(s->pb); ff_ape_parse_tag(s); if(!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) ff_id3v1_read(s); avio_seek(s->pb, cur, SEEK_SET); } return 0; }
static uint8_t* mxg_find_startmarker(uint8_t *p, uint8_t *end) { for (; p < end - 3; p += 4) { uint32_t x = AV_RN32(p); if (x & (~(x+0x01010101)) & 0x80808080) { if (p[0] == 0xff) { return p; } else if (p[1] == 0xff) { return p+1; } else if (p[2] == 0xff) { return p+2; } else if (p[3] == 0xff) { return p+3; } } } for (; p < end; ++p) { if (*p == 0xff) return p; } return end; }
static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int append) { WVContext *wc = ctx->priv_data; uint32_t tag, ver; int size; int rate, bpp, chan; uint32_t chmask; wc->pos = avio_tell(pb); if(!append) { tag = avio_rl32(pb); if (tag != MKTAG('w', 'v', 'p', 'k')) return AVERROR_INVALIDDATA; size = avio_rl32(pb); if(size < 24 || size > WV_BLOCK_LIMIT) { av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size); return AVERROR_INVALIDDATA; } wc->blksize = size; ver = avio_rl16(pb); if(ver < 0x402 || ver > 0x410) { av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return AVERROR_PATCHWELCOME; } avio_r8(pb); // track no avio_r8(pb); // track sub index wc->samples = avio_rl32(pb); // total samples in file wc->soff = avio_rl32(pb); // offset in samples of current block avio_read(pb, wc->extra, WV_EXTRA_SIZE); } else { size = wc->blksize; } wc->flags = AV_RL32(wc->extra + 4); // blocks with zero samples don't contain actual audio information and should be ignored if (!AV_RN32(wc->extra)) return 0; //parse flags bpp = ((wc->flags & 3) + 1) << 3; chan = 1 + !(wc->flags & WV_MONO); chmask = wc->flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; rate = wv_rates[(wc->flags >> 23) & 0xF]; wc->multichannel = !!((wc->flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK); if(wc->multichannel) { chan = wc->chan; chmask = wc->chmask; } if((rate == -1 || !chan) && !wc->block_parsed) { int64_t block_end = avio_tell(pb) + wc->blksize - 24; if(!pb->seekable) { av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return AVERROR_INVALIDDATA; } while(avio_tell(pb) < block_end) { int id, size; id = avio_r8(pb); size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb); size <<= 1; if(id&0x40) size--; switch(id&0x3F) { case 0xD: if(size <= 1) { av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n"); return AVERROR_INVALIDDATA; } chan = avio_r8(pb); switch(size - 2) { case 0: chmask = avio_r8(pb); break; case 1: chmask = avio_rl16(pb); break; case 2: chmask = avio_rl24(pb); break; case 3: chmask = avio_rl32(pb); break; case 5: avio_skip(pb, 1); chan |= (avio_r8(pb) & 0xF) << 8; chmask = avio_rl24(pb); break; default: av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size); return AVERROR_INVALIDDATA; } break; case 0x27: rate = avio_rl24(pb); break; default: avio_skip(pb, size); } if(id&0x40) avio_skip(pb, 1); } if(rate == -1) { av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, block_end - wc->blksize + 24, SEEK_SET); } if(!wc->bpp) wc->bpp = bpp; if(!wc->chan) wc->chan = chan; if(!wc->chmask) wc->chmask = chmask; if(!wc->rate) wc->rate = rate; if(wc->flags && bpp != wc->bpp) { av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return AVERROR_INVALIDDATA; } if(wc->flags && !wc->multichannel && chan != wc->chan) { av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return AVERROR_INVALIDDATA; } if(wc->flags && rate != -1 && rate != wc->rate) { av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return AVERROR_INVALIDDATA; } wc->blksize = size - 24; return 0; }
static int wv_read_packet(AVFormatContext *s, AVPacket *pkt) { WVContext *wc = s->priv_data; int ret; int size, ver, off; int64_t pos; uint32_t block_samples; if (s->pb->eof_reached) return AVERROR_EOF; if(wc->block_parsed) { if ((ret = wv_read_block_header(s, s->pb, 0)) < 0) return ret; } pos = wc->pos; off = wc->multichannel ? 4 : 0; if(av_new_packet(pkt, wc->blksize + WV_EXTRA_SIZE + off) < 0) return AVERROR(ENOMEM); if(wc->multichannel) AV_WL32(pkt->data, wc->blksize + WV_EXTRA_SIZE + 12); memcpy(pkt->data + off, wc->extra, WV_EXTRA_SIZE); ret = avio_read(s->pb, pkt->data + WV_EXTRA_SIZE + off, wc->blksize); if(ret != wc->blksize) { av_free_packet(pkt); return AVERROR(EIO); } while(!(wc->flags & WV_END_BLOCK)) { if(avio_rl32(s->pb) != MKTAG('w', 'v', 'p', 'k')) { av_free_packet(pkt); return AVERROR_INVALIDDATA; } if((ret = av_append_packet(s->pb, pkt, 4)) < 0) { av_free_packet(pkt); return ret; } size = AV_RL32(pkt->data + pkt->size - 4); if(size < 24 || size > WV_BLOCK_LIMIT) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Incorrect block size %d\n", size); return AVERROR_INVALIDDATA; } wc->blksize = size; ver = avio_rl16(s->pb); if(ver < 0x402 || ver > 0x410) { av_free_packet(pkt); av_log(s, AV_LOG_ERROR, "Unsupported version %03X\n", ver); return AVERROR_PATCHWELCOME; } avio_r8(s->pb); // track no avio_r8(s->pb); // track sub index wc->samples = avio_rl32(s->pb); // total samples in file wc->soff = avio_rl32(s->pb); // offset in samples of current block if((ret = av_append_packet(s->pb, pkt, WV_EXTRA_SIZE)) < 0) { av_free_packet(pkt); return ret; } memcpy(wc->extra, pkt->data + pkt->size - WV_EXTRA_SIZE, WV_EXTRA_SIZE); if ((ret = wv_read_block_header(s, s->pb, 1)) < 0) { av_free_packet(pkt); return ret; } ret = av_append_packet(s->pb, pkt, wc->blksize); if(ret < 0) { av_free_packet(pkt); return ret; } } pkt->stream_index = 0; wc->block_parsed = 1; pkt->pts = wc->soff; block_samples = AV_RN32(wc->extra); if (block_samples > INT32_MAX) av_log(s, AV_LOG_WARNING, "Too many samples in block: %"PRIu32"\n", block_samples); else pkt->duration = block_samples; av_add_index_entry(s->streams[0], pos, pkt->pts, 0, 0, AVINDEX_KEYFRAME); return 0; }
static int filter_frame(AVFilterLink *inlink, AVFrame *in) { AVFilterContext *ctx = inlink->dst; DrawGraphContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; AVDictionary *metadata; AVDictionaryEntry *e; AVFrame *out = s->out; int i; if (!s->out || s->out->width != outlink->w || s->out->height != outlink->h) { av_frame_free(&s->out); s->out = ff_get_video_buffer(outlink, outlink->w, outlink->h); out = s->out; if (!s->out) { av_frame_free(&in); return AVERROR(ENOMEM); } clear_image(s, out, outlink); } av_frame_copy_props(out, in); metadata = av_frame_get_metadata(in); for (i = 0; i < 4; i++) { double values[VAR_VARS_NB]; int j, y, x, old; uint32_t fg, bg; float vf; e = av_dict_get(metadata, s->key[i], NULL, 0); if (!e || !e->value) continue; if (sscanf(e->value, "%f", &vf) != 1) continue; vf = av_clipf(vf, s->min, s->max); values[VAR_MIN] = s->min; values[VAR_MAX] = s->max; values[VAR_VAL] = vf; fg = av_expr_eval(s->fg_expr[i], values, NULL); bg = AV_RN32(s->bg); if (i == 0 && s->x >= outlink->w) { if (s->slide == 0 || s->slide == 1) s->x = 0; if (s->slide == 2) { s->x = outlink->w - 1; for (j = 0; j < outlink->h; j++) { memmove(out->data[0] + j * out->linesize[0] , out->data[0] + j * out->linesize[0] + 4, (outlink->w - 1) * 4); } } else if (s->slide == 0) { clear_image(s, out, outlink); } } x = s->x; y = (outlink->h - 1) * (1 - ((vf - s->min) / (s->max - s->min))); switch (s->mode) { case 0: if (i == 0 && (s->slide == 1 || s->slide == 2)) for (j = 0; j < outlink->h; j++) draw_dot(bg, x, j, out); old = AV_RN32(out->data[0] + y * out->linesize[0] + x * 4); for (j = y; j < outlink->h; j++) { if (old != bg && (AV_RN32(out->data[0] + j * out->linesize[0] + x * 4) != old) || AV_RN32(out->data[0] + FFMIN(j+1, outlink->h - 1) * out->linesize[0] + x * 4) != old) { draw_dot(fg, x, j, out); break; } draw_dot(fg, x, j, out); } break; case 1: if (i == 0 && (s->slide == 1 || s->slide == 2)) for (j = 0; j < outlink->h; j++) draw_dot(bg, x, j, out); draw_dot(fg, x, y, out); break; case 2: if (s->first) { s->first = 0; s->prev_y[i] = y; } if (i == 0 && (s->slide == 1 || s->slide == 2)) { for (j = 0; j < y; j++) draw_dot(bg, x, j, out); for (j = outlink->h - 1; j > y; j--) draw_dot(bg, x, j, out); } if (y <= s->prev_y[i]) { for (j = y; j <= s->prev_y[i]; j++) draw_dot(fg, x, j, out); } else { for (j = s->prev_y[i]; j <= y; j++) draw_dot(fg, x, j, out); } s->prev_y[i] = y; break; } } s->x++; av_frame_free(&in); return ff_filter_frame(outlink, av_frame_clone(s->out)); }