PVOID sendVideoPackets()

in main/AppFileSrc.c [79:147]


PVOID sendVideoPackets(PVOID args)
{
    STATUS retStatus = STATUS_SUCCESS;
    PFileSrcContext pFileSrcContext = (PFileSrcContext) args;
    PCodecStreamConf pCodecStreamConf = NULL;
    Frame frame;
    UINT32 fileIndex = 0, frameSize;
    CHAR filePath[MAX_PATH_LEN + 1];
    STATUS status;
    UINT64 startTime, lastFrameTime, elapsed;

    CHK(pFileSrcContext != NULL, STATUS_MEDIA_NULL_ARG);

    pCodecStreamConf = &pFileSrcContext->codecConfiguration.videoStream;
    pCodecStreamConf->pFrameBuffer = (PBYTE) MEMALLOC(7*1024);
    pCodecStreamConf->frameBufferSize = 7*1024;
    frame.presentationTs = 0;
    startTime = GETTIME();
    lastFrameTime = startTime;

    while (!ATOMIC_LOAD_BOOL(&pFileSrcContext->shutdownFileSrc)) {
        fileIndex = fileIndex % NUMBER_OF_H264_FRAME_FILES + 1;
        snprintf(filePath, MAX_PATH_LEN, "/sdcard/h264SampleFrames/frame-%04d.h264", fileIndex);

        CHK(readFrameFromDisk(NULL, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_VIDEO_SINK);

        // Re-alloc if needed
        if (frameSize > pCodecStreamConf->frameBufferSize) {
            CHK((pCodecStreamConf->pFrameBuffer = (UINT8*) MEMREALLOC(pCodecStreamConf->pFrameBuffer, frameSize)) != NULL, STATUS_MEDIA_NOT_ENOUGH_MEMORY);
            pCodecStreamConf->frameBufferSize = frameSize;
        }

        // #TBD
        frame.flags = FRAME_FLAG_KEY_FRAME;
        frame.frameData = pCodecStreamConf->pFrameBuffer;
        frame.size = frameSize;

        CHK(readFrameFromDisk(frame.frameData, &frameSize, filePath) == STATUS_SUCCESS, STATUS_MEDIA_VIDEO_SINK);

        frame.presentationTs += FILESRC_VIDEO_FRAME_DURATION;
        frame.trackId = DEFAULT_VIDEO_TRACK_ID;
        frame.duration = 0;
        frame.version = FRAME_CURRENT_VERSION;
        frame.decodingTs = frame.presentationTs;
        if (pFileSrcContext->mediaSinkHook != NULL) {
            retStatus = pFileSrcContext->mediaSinkHook(pFileSrcContext->mediaSinkHookUserdata, &frame);
        }

        // Adjust sleep in the case the sleep itself and writeFrame take longer than expected. Since sleep makes sure that the thread
        // will be paused at least until the given amount, we can assume that there's no too early frame scenario.
        // Also, it's very unlikely to have a delay greater than FILESRC_VIDEO_FRAME_DURATION, so the logic assumes that this is always
        // true for simplicity.
        elapsed = lastFrameTime - startTime;
        THREAD_SLEEP(FILESRC_VIDEO_FRAME_DURATION - elapsed % FILESRC_VIDEO_FRAME_DURATION);
        lastFrameTime = GETTIME();
    }

CleanUp:
    if(pCodecStreamConf != NULL){
        SAFE_MEMFREE(pCodecStreamConf->pFrameBuffer);
    }
    CHK_LOG_ERR(retStatus);
    /* free resources */
    DLOGD("terminating media source");
    if (pFileSrcContext->mediaEosHook != NULL) {
        retStatus = pFileSrcContext->mediaEosHook(pFileSrcContext->mediaEosHookUserdata);
    }
    return (PVOID) (ULONG_PTR) retStatus;
}