If I remove this one line of code:
printf("Creating test.\n");
It won't work. I've got everything working except with the slight problem that the program crashes when it gets to the end if I don't remove this line.
I don't get it printf is a simple print to console command, how the hell is it doing anything?
Alright before my head explodes here's my code:
//SDL_Movie.h
#include "SDL.h"
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
int SDL_MOVIE_ERROR = 0;
typedef struct SDL_Movie {
int videoStream, audioStream;
AVFormatContext* pFormatCtx;
AVCodecContext* pCodecCtx;
AVCodecContext* aCodecCtx;
AVCodec* pCodec;
AVCodec* aCodec;
AVFrame* pFrame;
AVFrame* pFrameRGB;
} SDL_Movie;
char *SDL_Movie_GetError()
{
char* error;
switch (SDL_MOVIE_ERROR)
{
case 0:
error = "Unknown/No error.";
break;
case 1:
error = "Error opening file.";
break;
case 2:
error = "Couldn't find stream information.";
break;
case 3:
error = "Couldn't find video stream.";
break;
case 4:
error = "Couldn't find audio stream";
break;
case 5:
error = "Unsupported video codec.";
break;
case 6:
error = "Unsupported audio codec.";
break;
case 7:
error = "Video codec could not be opened.";
break;
case 8:
error = "Couldn't allocate frame.";
break;
default:
error = "Unknown/No error.";
break;
}
SDL_MOVIE_ERROR = 0;
return error;
}
SDL_Movie *SDL_LoadMovie(const char *file) {
SDL_Movie *mov;
printf("Entered.\n");
int ret;
mov->pFormatCtx = NULL;
if ((ret = avformat_open_input(&mov->pFormatCtx, file, NULL, NULL)) < 0)
{
printf("Failure.\n");
SDL_MOVIE_ERROR = 1;
return NULL;
}
printf("Opened.\n");
if (avformat_find_stream_info(mov->pFormatCtx, NULL) < 0)
{
SDL_MOVIE_ERROR = 2;
return NULL;
}
int i;
mov->videoStream = -1;
mov->audioStream = -1;
for (i=0; i < mov->pFormatCtx->nb_streams; i++)
{
if (mov->pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && mov->videoStream < 0)
mov->videoStream=i;
if (mov->pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && mov->audioStream < 0)
mov->audioStream = i;
}
if (mov->videoStream == -1)
{
SDL_MOVIE_ERROR = 3;
return NULL;
}
if (mov->audioStream == -1)
{
SDL_MOVIE_ERROR = 4;
return NULL;
}
mov->pCodecCtx = mov->pFormatCtx->streams[mov->videoStream]->codec;
mov->aCodecCtx = mov->pFormatCtx->streams[mov->audioStream]->codec;
if (!(mov->pCodec = avcodec_find_decoder(mov->pCodecCtx->codec_id)))
{
SDL_MOVIE_ERROR = 5;
return NULL;
}
if (!(mov->aCodec = avcodec_find_decoder(mov->aCodecCtx->codec_id)))
{
SDL_MOVIE_ERROR = 6;
return NULL;
}
if (avcodec_open(mov->pCodecCtx, mov->pCodec) < 0)
{
SDL_MOVIE_ERROR = 7;
return NULL;
}
avcodec_open(mov->aCodecCtx, mov->aCodec);
mov->pFrame = avcodec_alloc_frame();
mov->pFrameRGB = avcodec_alloc_frame();
if (!mov->pFrameRGB)
{
SDL_MOVIE_ERROR = 8;
return NULL;
}
uint8_t* buffer;
int numBytes = avpicture_get_size(PIX_FMT_RGB24, mov->pCodecCtx->width, mov->pCodecCtx->height);
buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
avpicture_fill((AVPicture *)mov->pFrameRGB, buffer, PIX_FMT_RGB24, mov->pCodecCtx->width, mov->pCodecCtx->height);
int frameFinished;
AVPacket packet;
av_free(buffer);
return mov;
}
//main.c
#include <SDL.h>
#include "SDL_Movie.h"
#include <SDL_mixer.h>
#include <SDL_thread.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
SDL_Surface* screen = NULL;
int quit = 0;
SDL_Event event;
/*
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
FILE *pFile;
char szFilename[32];
int y;
// Open file
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename, "wb");
if(pFile==NULL)
return;
// Write header
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
// Write pixel data
for(y=0; y<height; y++)
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
// Close file
fclose(pFile);
}
*/
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return 1;
atexit(SDL_Quit);
av_register_all();
printf("Creating test.\n");
SDL_Movie* test = SDL_LoadMovie("nuke.mp4");
printf("Created test.\n");
if (!test)
printf("%s", SDL_Movie_GetError());
if (!(screen = SDL_SetVideoMode(/*pCodecCtx->width, pCodecCtx->height,*/ 1680, 1050, 24, SDL_HWSURFACE | SDL_ANYFORMAT)))
return 1;
SDL_Overlay* bmp = SDL_CreateYUVOverlay(test->pCodecCtx->width, test->pCodecCtx->height, SDL_YV12_OVERLAY, screen);
int frameFinished;
AVPacket packet;
int i = 0;
while (av_read_frame(test->pFormatCtx, &packet) >= 0) {
if (packet.stream_index == test->videoStream) {
avcodec_decode_video2(test->pCodecCtx, test->pFrame, &frameFinished, &packet);
SDL_Rect rect;
if (frameFinished) {
SDL_LockYUVOverlay(bmp);
/*struct SwsContext* swsContext = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(swsContext, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
if (++i <= 70)
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
*/
AVPicture pict;
pict.data[0] = bmp->pixels[0];
pict.data[1] = bmp->pixels[2];
pict.data[2] = bmp->pixels[1];
pict.linesize[0] = bmp->pitches[0];
pict.linesize[1] = bmp->pitches[2];
pict.linesize[2] = bmp->pitches[1];
struct SwsContext* swsContext = sws_getContext(test->pCodecCtx->width, test->pCodecCtx->height, test->pCodecCtx->pix_fmt, test->pCodecCtx->width, test->pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(swsContext, test->pFrame->data, test->pFrame->linesize, 0, test->pCodecCtx->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(bmp);
rect.x = 0;
rect.y = 0;
//rect.w = pCodecCtx->width;
//rect.h = pCodecCtx->height;
rect.w = 1680;
rect.h = 1050;
SDL_DisplayYUVOverlay(bmp, &rect);
}
}
}
//av_free(buffer);
av_free(test->pFrameRGB);
av_free(test->pFrame);
avcodec_close(test->pCodecCtx);
av_close_input_file(test->pFormatCtx);
return 0;
}
The main function is where I use the printf function that fixes almost everything.
If I don't have it, the program returns 3 when I call avformat_open_input in the SDL_LoadMovie function.
I just don't get it. Can anyone make sense of this?






