Как добиться лучшего качества с помощью libav на поверхности Android? - PullRequest
0 голосов
/ 16 ноября 2018

Воспроизведение видео из потока RTSP на поверхности Android с использованием решения из этого репозитория https://github.com/alexandruc/android-ffmpeg-player/blob/master/android-ffmpeg-player/jni/ffmpeg-player.c

Видео воспроизводится, но имеет много глюков, особенно когда что-то движется.Не хватило опыта, используя libav .Будем рады, если кто-то может помочь или дать ссылки на некоторые учебные пособия или сообщество.

Вот функция для отображения видео на поверхности.

void* decodeAndRender(void *voidArgs) {
auto *args = (decode_args*)voidArgs;
CamCon* cc = getCamCon(args->name);

ANativeWindow_Buffer    windowBuffer;
AVPacket                packet;
int                     i=0;
int                     frameFinished;
int                     lineCnt;

int counter = 0;
while(av_read_frame(cc->formatCtx, &packet)>=0 && cc->isConnect) {
    counter = 1;
    // Is this a packet from the video stream?
    if(packet.stream_index==cc->videoStreamIdx) {
        // Decode video frame
        avcodec_decode_video2(cc->codecCtx, cc->decodedFrame, &frameFinished, &packet);
        // Did we get a video frame?
        if(frameFinished) {
            // RECORD video
            if(cc->isRecord)
                recordMP4(packet, cc);

            // DISPLAY video
            // Convert the image from its native format to RGBA
            sws_scale (
                    cc->sws_ctx,
                    (uint8_t const * const *)cc->decodedFrame->data,
                    cc->decodedFrame->linesize,
                    0,
                    cc->codecCtx->height,
                    cc->frameRGBA->data,
                    cc->frameRGBA->linesize
            );
            // lock the window buffer
            if (ANativeWindow_lock(cc->window, &windowBuffer, NULL) < 0) {
                LOGE("cannot lock window");
            } else {
                // draw the frame on buffer
                LOGI("copy buffer %d:%d:%d", cc->displayWidth, cc->displayHeight, cc->displayWidth * cc->displayHeight*4);
                LOGI("window buffer: %d:%d:%d", windowBuffer.width,
                     windowBuffer.height, windowBuffer.stride);
                memcpy(windowBuffer.bits, cc->buffer,  cc->displayWidth * cc->displayHeight * 4);
                // unlock the window buffer and post it to display
                ANativeWindow_unlockAndPost(cc->window);
                // count number of frames
                ++i;
            }
        }
    }
    // Free the packet that was allocated by av_read_frame
    av_free_packet(&packet);
}
LOGI("total No. of frames decoded and rendered %d", i);
finish(args->env, args->name);

}

...