@@ -120,6 +120,8 @@ typedef struct {
int coursecount; /* counter from 0 to 89 */
int midcourse; /* whether it is a coursesignature beginning from 45 + i * 90 */
uint32_t lastindex; /* helper to store amount of frames */
+
+ int exported; /* boolean whether stream already exported */
} StreamContext;
typedef struct {
@@ -71,6 +71,7 @@ AVFILTER_DEFINE_CLASS(signature);
static int query_formats(AVFilterContext *ctx)
{
+ /* all formats with a seperate gray value */
static const enum AVPixelFormat pix_fmts[] = {
AV_PIX_FMT_GRAY8,
AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
@@ -586,21 +587,56 @@ static int export(AVFilterContext *ctx, StreamContext *sc, int input)
static int request_frame(AVFilterLink *outlink)
{
AVFilterContext *ctx = outlink->src;
- SignatureContext *sc = ctx->priv;
- int i, ret;
+ SignatureContext *sic = ctx->priv;
+ StreamContext *sc, *sc2;
+ MatchingInfo match;
+ int i, j, ret;
+ int lookup = 1; /* indicates wheather EOF of all files is reached */
+
+ /* process all inputs */
+ for (i = 0; i < sic->nb_inputs; i++){
+ sc = &(sic->streamcontexts[i]);
- for (i = 0; i < sc->nb_inputs; i++){
ret = ff_request_frame(ctx->inputs[i]);
- // TODO handle this in a better way?
- // Problem is the following:
- // Assuming two inputs, inputA with 50 frames, inputB with 100 frames
- // simply returning ret when < 0 would result in not filtering inputB
- // after 50 frames anymore, not wanted
- // only returning ret at the end would result in only respecting the error
- // values of the last input, please comment
+
+ /* return if unexspected error occurs in input stream */
if (ret < 0 && ret != AVERROR_EOF)
return ret;
+
+ /* export signature at EOF */
+ if (ret == AVERROR_EOF){
+ /* export if wanted */
+ if (strlen(sic->filename) > 0) {
+ if (export(ctx, sc, i) < 0)
+ return ret;
+ }
+ sc->exported = 1;
+ }
+ lookup &= sc->exported;
+ }
+
+ /* signature lookup */
+ if (lookup && sic->mode != MODE_OFF) {
+ /* iterate over every pair */
+ for (i = 0; i < sic->nb_inputs; i++) {
+ sc = &(sic->streamcontexts[i]);
+ for (j = i+1; j < sic->nb_inputs; j++) {
+ sc2 = &(sic->streamcontexts[j]);
+ match = lookup_signatures(ctx, sic, sc, sc2, sic->mode);
+ if (match.score != 0) {
+ av_log(ctx, AV_LOG_INFO, "matching of video %d at %f and %d at %f, %d frames matching\n",
+ i, ((double) match.first->pts * sc->time_base.num) / sc->time_base.den,
+ j, ((double) match.second->pts * sc2->time_base.num) / sc2->time_base.den,
+ match.matchframes);
+ if (match.whole)
+ av_log(ctx, AV_LOG_INFO, "whole video matching\n");
+ } else {
+ av_log(ctx, AV_LOG_INFO, "no matching of video %d and %d\n", i, j);
+ }
+ }
+ }
}
+
return ret;
}
@@ -663,52 +699,14 @@ static av_cold int init(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
{
SignatureContext *sic = ctx->priv;
- StreamContext *sc, *sc2;
+ StreamContext *sc;
void* tmp;
FineSignature* finsig;
CourseSignature* cousig;
- MatchingInfo match;
- int i,j;
-
- //TODO export and especially lookup_signature can have a return value to show some error etc.
- //How could this be handled in this function?
+ int i;
- /* signature export */
- if (strlen(sic->filename) > 0) {
- for (i = 0; i < sic->nb_inputs; i++) {
- /* if filter frame was called at least once */
- if (&(sic->streamcontexts[i]) && (&(sic->streamcontexts[i]))->curfinesig)
- export(ctx, &(sic->streamcontexts[i]), i);
- }
- }
-
- /* signature lookup */
- if (sic->mode != MODE_OFF) {
- /* iterate over every pair */
- for (i = 0; i < sic->nb_inputs; i++) {
- sc = &(sic->streamcontexts[i]);
- if (sc && sc->curfinesig) {
- for (j = i+1; j < sic->nb_inputs; j++) {
- sc2 = &(sic->streamcontexts[j]);
- if (sc2 && sc2->curfinesig) {
- match = lookup_signatures(ctx, sic, sc, sc2, sic->mode);
- if (match.score != 0) {
- av_log(ctx, AV_LOG_INFO, "matching of video %d at %f and %d at %f, %d frames matching\n",
- i, ((double) match.first->pts * sc->time_base.num) / sc->time_base.den,
- j, ((double) match.second->pts * sc2->time_base.num) / sc2->time_base.den,
- match.matchframes);
- if (match.whole)
- av_log(ctx, AV_LOG_INFO, "whole video matching\n");
- } else {
- av_log(ctx, AV_LOG_INFO, "no matching of video %d and %d\n", i, j);
- }
- }
- }
- }
- }
- }
- /* cleanup */
+ /* free the lists */
if (sic->streamcontexts != NULL) {
for (i = 0; i < sic->nb_inputs; i++) {
sc = &(sic->streamcontexts[i]);