FFMS / ffms2

An FFmpeg based source library and Avisynth/VapourSynth plugin for easy frame accurate access
Other
576 stars 104 forks source link

Getting strange artifacts as output #329

Closed oierlauzi closed 5 years ago

oierlauzi commented 6 years ago

Hello. I'm getting strange output results with FFMS2. Here goes a pic. imagen

The code I'm using is pretty similar to the one in the documentation pages. However I'll attach it: FFMS_Init(0, 0) has been executed before

    //Create the indexer
    FFMS_Indexer * indexer =FFMS_CreateIndexer(dir, NULL);
    if(!indexer){
        free(encVideo);
        return NULL;
    }

    //Create an index of all tracks
    FFMS_Index * index =FFMS_DoIndexing2(indexer, FFMS_IEH_ABORT, NULL);
    if(!index){
        free(encVideo);
        return NULL;
    }

    //Get the video track of the file. It needs to be greater than 0, if not, it means that here are no video tracks
    int track=FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, NULL);
    if(track<0){
        FFMS_DestroyIndex(index);
        free(encVideo);
        return NULL;
    }

    //Create the video source
    FFMS_VideoSource * videosource =FFMS_CreateVideoSource(dir, track, index, systemCoreCount, FFMS_SEEK_NORMAL, NULL);
    FFMS_DestroyIndex(index); //Index is not longer needed
    if(!videosource){
        free(encVideo);
        return NULL;
    }
    encVideo->videoSrc=videosource;

    //Get the video properties
    const FFMS_VideoProperties * props =FFMS_GetVideoProperties(videosource);
    const FFMS_Frame *propFrame=FFMS_GetFrame(videosource, 0, NULL);

    encVideo->width=propFrame->EncodedWidth;
    encVideo->height=propFrame->EncodedHeight;
    encVideo->frames=props->NumFrames;
    encVideo->duration=(props->LastTime-props->FirstTime)*1000;

    //Set up the video converter
    int pixfmts[]={AV_PIX_FMT_RGBA, -1};

    if(FFMS_SetOutputFormatV2(videosource, pixfmts, encVideo->width, encVideo->height, FFMS_RESIZER_BICUBIC, NULL)){
        FFMS_DestroyVideoSource(videosource);
        free(encVideo);
        return NULL;
    }
//Reading frame by frame
    const FFMS_Frame * frame=FFMS_GetFrameByTime(encVideo->videoSrc, (double)us/1000000, NULL);
    if(!frame)
        return NULL;
    if(!frame->Linesize[0])
        return NULL;

    tPagadiMemFrame * memFrame=createPagadiMemFrame(encVideo->width, encVideo->height, frame->Data[0]);
    return memFrame;

where createPagadiMemFrame mempy-s the given data EDIT: if I set up FFMS_ErrorInfo, it gives no error message EDIT2: Using FFMS_GetPixFmt("rgba"); does not solve the problem

dwbuiten commented 5 years ago

You can't memcpy just width * height bytes from frame->Data[0], since the stride is not necessarily the width, and also AV_PIX_FMT_RGBA is a packd format; this is how video works in every framework/codebase/etc/in general. RGBA happens to have only one plane (since it is packed), but other formats will have more, anda just Data[0] may not be sufficient.

You'd need to do something like this for RGBA:

uint8_t *buf = malloc(width * height * 4);
if (buf == NULL) {
    //error
}
for (int y = 0; y < frame->Height; y++) {
    memcpy(buf + width * y * 4, frame->Data[0] + y * frame->Linesize[0], width * 4);
}

Closing as this isnt a FFMS2 bug.

sekrit-twc commented 5 years ago

See this explanatory MSPaint document:

layout