I am writting simple video player in android , but unfortunately the images are getting flickered. Would you mind locating where is the issue from SDL front.
What i am trying to achieve is :
- Get the complete frame from ffmpeg,
- Update into texture & render.
- I have hard coded the Height/Width value ,1280, 720, as i am getting the same from streaming server. [ i dont depend on it from context, as it does not provide initially unless i retrieve some packet ]
Issue:
Flickering image.
I am not sure if any buffer overflow happens from the SDL side.
Here is the code.
av_register_all();
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
LOGD ( "Could not initialize SDL - %s\n", SDL_GetError());
exit(1);
}
if (avformat_open_input(&pFormatCtx, "rtsp://192.168.6.1:8554/h264ESVideoTest", NULL, NULL) != 0)
return -1; // Couldn't open file
// Retrieve stream information
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
return -1; // Couldn't find stream information
// Find the first video stream
videoStream = -1;
for (i = 0; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStream = i;
break;
}
if (videoStream == -1)
return -1;
// Get a pointer to the codec context for the video stream
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
LOGD ("Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
return -1; // Could not open codec
// Allocate video frame
pFrame = avcodec_alloc_frame();
screen = SDL_CreateWindow ("Testing..",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, \
SDL_WINDOW_SHOWN|SDL_WINDOW_ALLOW_HIGHDPI );
if (!screen) {
fprintf(stderr, "SDL: could not set video mode - exiting\n");
exit(1);
}
renderer = SDL_CreateRenderer (screen, -1, SDL_RENDERER_ACCELERATED| SDL_RENDERER_TARGETTEXTURE);
bmp = SDL_CreateTexture (renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING,1280, 720);
i = 0;
while (av_read_frame(pFormatCtx, &packet) >= 0) {
if (packet.stream_index == videoStream) {
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
if (frameFinished) {
SDL_UpdateYUVTexture(bmp, NULL, pFrame->data[0], pFrame->linesize[0], \
pFrame->data[1], pFrame->linesize[1], \
pFrame->data[2], pFrame->linesize[2]);
}
}
av_free_packet(&packet);
SDL_RenderClear(renderer);
retcopy = SDL_RenderCopy(renderer, bmp, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_PollEvent(&event);
switch (event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
case SDL_KEYDOWN:
SDL_Quit ();
exit (0);
default:
break;
}
}
av_free(pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}