Sorry had a wrong loop on previous file. This should do it.
thanks
/*
- test2.c*
- Created on: Mar 9, 2012
-
Author: dvi
*/
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <SDL.h>
#include <stdio.h>
void sdl_init(AVFormatContext* format_context, AVCodecContext*
codec_context, int videostream ) {
SDL_Init(SDL_INIT_EVERYTHING);
AVFrame* frame;
AVFrame *pFrameRGB;
AVPacket avpacket;
AVPicture picture;
// Convert the image from its native format to RGB
struct SwsContext *img_convert_ctx =NULL;
SDL_Event event;
SDL_RendererInfo info;
SDL_Texture *texture;
SDL_Surface *image;
Uint32 then, now , frames;
int w = 640;
int h = 480;
int done = 0;
SDL_Window * window = SDL_CreateWindow("SDL",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_GetRendererInfo(renderer, &info);
printf("Using %s rendering\n", info.name);
SDL_Log("+++++ INIT DONE +++++");
frame = avcodec_alloc_frame();
pFrameRGB = avcodec_alloc_frame();
if (pFrameRGB == NULL)
{
printf("Cannot allocate pFrame\n");
exit(-1);
}
unsigned char* pixels;
int pitch;
uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, codec_context->width,
codec_context->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
codec_context->width, codec_context->height);
while (av_read_frame(format_context, &avpacket) >= 0) {
if (avpacket.stream_index == videostream) {
// Video stream packet
int frame_finished;
avcodec_decode_video2(codec_context, frame, &frame_finished,
&avpacket);
if(frame_finished)
{
picture.data[0] = frame->data[0];
picture.data[1] = frame->data[1];
picture.data[2] = frame->data[2];
picture.linesize[0] = frame->linesize[0];
picture.linesize[1] = frame->linesize[1];
picture.linesize[2] = frame->linesize[2];
img_convert_ctx = sws_getCachedContext(img_convert_ctx,
codec_context->width,
codec_context->height,
PIX_FMT_YUV420P,
frame->width,
frame->height,
PIX_FMT_RGB24,
SWS_BICUBIC,
NULL,
NULL,
NULL);
if (img_convert_ctx == NULL)
{
fprintf(stderr, "Cannot initialize the conversion context!\n");
exit(1);
}
int s = sws_scale(
img_convert_ctx,
frame->data,
frame->linesize,
0,
codec_context->height,
picture.data,
picture.linesize);
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12,
SDL_TEXTUREACCESS_STREAMING, codec_context->width,
codec_context->height);//3 plane texture
if (!texture) {
fprintf(stderr, "Couldn't set create texture: %s\n",
SDL_GetError());
exit(-1);
}
if(texture && !SDL_LockTexture(texture, NULL, (void **)&pixels,
&pitch) ) {
if(pitch == picture.linesize[0]) {
int size = pitch * frame->height;
memcpy(pixels, picture.data[0], size);
memcpy(pixels + size, picture.data[2], size / 4);
memcpy(pixels + size * 5 / 4, picture.data[1], size / 4);
}
else {
register unsigned char *y1,*y2,*y3,*i1,*i2,*i3;
int i;
y1 = pixels;
y3 = pixels + pitch * frame->height; // invertiti xche' avevo i
colori sballati!
y2 = pixels + pitch * frame->height * 5 / 4;
i1=picture.data[0];
i2=picture.data[1];
i3=picture.data[2];
for (i = 0; i<(frame->height/2); i++) {
memcpy(y1,i1,pitch);
i1+=picture.linesize[0];
y1+=pitch;
memcpy(y1,i1,pitch);
memcpy(y2,i2,pitch / 2);
memcpy(y3,i3,pitch / 2);
y1+=pitch;
y2+=pitch / 2;
y3+=pitch / 2;
i1+=picture.linesize[0];
i2+=picture.linesize[1];
i3+=picture.linesize[2];
}
}
}//texture
SDL_UnlockTexture(texture);
}//frame
av_free_packet(&avpacket);
}//avpacket
//while (!done) {
SDL_PollEvent(&event);
switch(event.type) {
if (event.key.keysym.sym == SDLK_ESCAPE) {
done = 1;
}
break;
case SDL_QUIT:
//done=1;
SDL_Log("Unhandled event type=%d", event.type);
done=1;
break;
}
/* Print out some timing information */
// printf("TIMING %d\n",avpacket.dts);
//SDL_UpdateTexture(texture, NULL, imageYUV, image->w)
if (!SDL_UpdateTexture(texture, NULL, frame, frame->width)) {
//SDL_UpdateTexture(texture, NULL, imageYUV, image->w);
fprintf(stderr, "Couldn't update texture: %s\n",
SDL_GetError());
//exit(-1);
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
SDL_Delay(20);
//}
// }
}//while av_read_frame
SDL_Log("+++++ FINISHED +++++");
SDL_Quit();
}
int main(int argc, char * argv) {
AVCodecContext* codec_context;
int videostream;
if (argc < 2) {
printf("Usage: %s filename\n", argv[0]);
return 0;
}
// Register all available file formats and codecs
av_register_all();
int err;
// Init SDL with video support
err = SDL_Init(SDL_INIT_VIDEO);
if (err < 0) {
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
return -1;
}
// Open video file
const char* filename = argv[1];
AVFormatContext* format_context = NULL;
err = avformat_open_input(&format_context, filename, NULL, NULL);
if (err < 0) {
fprintf(stderr, "ffmpeg: Unable to open input\n");
return -1;
}
// Retrieve stream information
err = avformat_find_stream_info(format_context, NULL);
if (err < 0) {
fprintf(stderr, "ffmpeg: Unable to find stream info\n");
return -1;
}
// Dump information about file onto standard error
av_dump_format(format_context, 0, argv[1], 0);
// Find the first video stream
for (videostream = 0; videostream < format_context->nb_streams;
++videostream) {
if (format_context->streams[videostream]->codec->codec_type ==
AVMEDIA_TYPE_VIDEO) {
break;
}
}
if (videostream == format_context->nb_streams) {
fprintf(stderr, “ffmpeg: Unable to find video stream\n”);
return -1;
}
codec_context = format_context->streams[videostream]->codec;
AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
avcodec_alloc_context3(codec);
if (avcodec_open2(codec_context, codec, NULL) < 0)
{
fprintf(stderr, "ffmpeg: Unable to allocate codec context\n");
}
else {
printf("Codec initialized\n");
}
/*
Initializing display
*/
printf("Width:%d\n",codec_context->width);
printf("height:%d\n",codec_context->height);
//exit(0);
sdl_init(format_context, codec_context,videostream);
return 0;
}
On 03/09/2012 11:09 AM, David martin wrote:
Hi,
I’m new to SDL2, I used to play with danger ffmpeg tutorials to stream
video to an SDL surface.
I’m updating my program incorporating SDL2.
Here is a piece of snippet and would appreciate your help to actually
draw the video image into the surface using the SDL2 api.
thanks
…
AVFrame* frame ;
AVPacket avpacket;
int frame_finished;
SDL_Event event;
int w = 640;
int h = 480;
int done = 0, color = 0;
SDL_Window * window = SDL_CreateWindow(“SDL”, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, w, h, 0);
SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Log(“+++++ INIT DONE +++++”);
frame = avcodec_alloc_frame();
while (av_read_frame(format_context, &avpacket) >= 0) {
if (avpacket.stream_index == videostream) {
avcodec_decode_video2(codec_context, frame, &frame_finished, &avpacket);
}
while (!done) {
SDL_WaitEvent(&event);
switch(event.type) {
//case FF_ALLOC_EVENT:
//alloc_picture(event.user.data1);
// break;
//case FF_REFRESH_EVENT:
//video_refresh_timer(event.user.data1);
// break;
case SDL_KEYDOWN:
case SDL_KEYUP:
//case SDL_MOUSEBUTTONDOWN:
case SDL_QUIT:
done=1;
SDL_Log(“Unhandled event type=%d”, event.type);
}
//Draw Image into renderer.
//We used to do it through SDL_DisplayYUVOverlay. How to do that with
SDL2.0. Any help for this part ?
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
SDL_Delay(20);
}
}//while av_read_frame
SDL_Log(“+++++ FINISHED +++++”);
SDL_Quit();
}