Ejemplo n.º 1
0
static int
resizePlayer(ffmpegPlayer *me)
{
	/* resizePlayer may be called before any size allocation */
	int widget_w = AGWIDGET(me)->w > 0 ? AGWIDGET(me)->w : me->w;
	int widget_h = AGWIDGET(me)->h > 0 ? AGWIDGET(me)->h : me->h;

	if (me->flags & AG_FFMPEGPLAYER_KEEPRATIO) {
		int film_w, film_h;
		float aspect;

		SDL_ffmpegGetVideoSize(me->file, &film_w, &film_h);
		aspect = (float)film_h / film_w;

		if (widget_w * aspect > widget_h) {
			me->disp_w = SCALE_FLOOR((int)(widget_h / aspect));
			me->disp_h = SCALE_FLOOR(widget_h);
		} else {
			me->disp_w = SCALE_FLOOR(widget_w);
			me->disp_h = SCALE_FLOOR((int)(widget_w * aspect));
		}
	} else {
		me->disp_w = SCALE_FLOOR(widget_w);
		me->disp_h = SCALE_FLOOR(widget_h);
	}

#ifndef USE_OVERLAY
	for (int i = 0; i < FFMPEGPLAYER_BUFSIZE; i++) {
		SDL_ffmpegVideoFrame *frame = me->videoFrame[i];

		if (frame->surface != NULL)
			SDL_FreeSurface(frame->surface);

		frame->surface = SDL_CreateRGBSurface(SDL_HWSURFACE,
						      me->disp_w, me->disp_h, 24,
						      htonl(0xFF000000),
						      htonl(0x00FF0000),
						      htonl(0x0000FF00), 0x0);
		if (frame->surface == NULL)
			/* FIXME */
			return -1;

		SDL_ffmpegGetVideoFrame(me->file, frame);
	}
	me->curVideoFrame = 0;
#endif

	return 0;
}
Ejemplo n.º 2
0
int main(int argc, char** argv) {
	SDL_ffmpegFile* film;
	int s;
	SDL_ffmpegStream *str;
	SDL_AudioSpec *specs;
	int w,h;
	int done = 0;
	SDL_Surface *screen;

	/* check if we got an argument */
	if(argc < 2) {
		printf("usage: \"%s\" \"filename\"\n", argv[0]);
		return -1;
	}
	/* standard SDL initialization stuff */
	if(SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_DOUBLEBUF) < 0) {
		fprintf(stderr, "problem initializing SDL: %s\n", SDL_GetError());
		return -1;
	}

	/* open file from arg[1] */
	film = SDL_ffmpegOpen(argv[1]);
	if(!film) {
		printf("error opening file\n");
		return -1;
	}

	/* print some info on detected stream to output */

	for(s = 0; s<film->AStreams; s++) {
		str = SDL_ffmpegGetAudioStream(film, s);

		printf("Info on audiostream #%i:\n", s);
		printf("\tChannels: %i\n",      str->channels);
		if(strlen(str->language)) printf("\tLanguage: %s\n",      str->language);
		printf("\tSampleRate: %i\n",    str->sampleRate);
	}

	for(s = 0; s<film->VStreams; s++) {
		str = SDL_ffmpegGetVideoStream(film, s);

		printf("Info on videostream #%i:\n", s);
		if(strlen(str->language)) printf("\tLanguage: %s\n",      str->language);
		printf("\tFrame: %ix%i\n",  str->width, str->height);
		printf("\tFrameRate: %.2ffps\n",  1.0 / (str->frameRate[0] / str->frameRate[1]));
	}

	/* select the streams you want to decode (example just uses 0 as a default) */
	SDL_ffmpegSelectVideoStream(film, 0);
	SDL_ffmpegSelectAudioStream(film, 0);

	/* get the audiospec which fits the selected videostream, if no videostream */
	/* is selected, default values are used (2 channel, 48Khz) */
	specs = SDL_ffmpegGetAudioSpec(film, 512, audioCallback);

	/* we get the size from our active video stream, if no active video stream */
	/* exists, width and height are set to default values (320x240) */
	SDL_ffmpegGetVideoSize(film, &w, &h);

	/* Open the Video device */
	screen = SDL_SetVideoMode(w, h, 32, SDL_DOUBLEBUF|SDL_HWSURFACE);
	if(!screen) {
		printf("Couldn't open video: %s\n", SDL_GetError());
		return -1;
	}

	/* Open the Audio device */
	if( SDL_OpenAudio(specs, 0) < 0 ) {
		printf("Couldn't open audio: %s\n", SDL_GetError());
		return -1;
	}

	/* we start our decode thread, this always tries to buffer in some frames */
	/* so we can enjoy smooth playback */
	SDL_ffmpegStartDecoding(film);

	/* we unpause the audio so our audiobuffer gets read */
	SDL_PauseAudio(0);


	while( !done ) {
		SDL_ffmpegVideoFrame* frame;

		/* just some standard SDL event stuff */
		SDL_Event event;
		while(SDL_PollEvent(&event)) {

			if(event.type == SDL_QUIT) {
				done = 1;
				break;
			}

			if(event.type == SDL_MOUSEBUTTONDOWN) {
				int x,y;
				int64_t time;
				SDL_PumpEvents();

				SDL_GetMouseState(&x, &y);
				/* by clicking you turn on the stream, seeking to the percentage */
				/* in time, based on the x-position you clicked on */
				time = ((double)x / w) * SDL_ffmpegGetDuration(film);

				/* we seek to time (milliseconds) */
				SDL_ffmpegSeek(film, time);

				/* by passing 0(false) as our second argument, we play the file */
				/* passing a non-zero value would mean we pause our file */
				SDL_ffmpegPause(film, 0);
			}
		}

		/* we retrieve the current image from the file */
		/* we get 0 if no file could be retrieved */
		/* important! please note this call should be paired with SDL_ffmpegReleaseVideo */
		frame = SDL_ffmpegGetVideoFrame(film);

		if(frame) {

			/* we got a frame, so we better show this one */
			SDL_BlitSurface(frame->buffer, 0, screen, 0);

			/* After releasing this frame, you can no longer use it. */
			/* you should call this function every time you get a frame! */
			SDL_ffmpegReleaseVideo(film, frame);

			/* we flip the double buffered screen so we might actually see something */
			SDL_Flip(screen);
		}

		/* we wish not to kill our poor cpu, so we give it some timeoff */
		SDL_Delay(5);
	}

	/* after all is said and done, we should call this */
	SDL_ffmpegFree(film);

	/* the SDL_Quit function offcourse... */
	SDL_Quit();

	return 0;
}
Ejemplo n.º 3
0
static void *
drawVideoThread(void *data)
{
	ffmpegPlayer *me = data;

	AG_ObjectLock(me);

	for (;;) {
		SDL_ffmpegVideoFrame *frame = me->videoFrame[me->curVideoFrame];

		if (!frame->ready) {
			DEBUG("Video buffer underrun!");
			SDL_ffmpegGetVideoFrame(me->file, frame);
		}

		uint64_t sync = getSync(me);
		uint64_t pts = frame->pts;

		if (pts >= sync) {
			AG_ObjectUnlock(me);
			/* condition variable waiting may be faster, test with 500mhz */
			AG_Delay(pts - sync);
			AG_ObjectLock(me);
			if (me->file == NULL) {
				/* FIXME */
				break;
			}

			if (pts > getSync(me))
				continue;

#ifdef USE_OVERLAY
			if (frame->overlay != NULL) {
				if (AG_WidgetVisible(me)) {
					int frame_x = (AGWIDGET(me)->w - me->disp_w) / 2;
					int frame_y = (AGWIDGET(me)->h - me->disp_h) / 2;

					SDL_Rect rect = {
						.x = AGWIDGET(me)->rView.x1 + frame_x,
						.y = AGWIDGET(me)->rView.y1 + frame_y,
						.w = me->disp_w,
						.h = me->disp_h
					};
					SDL_DisplayYUVOverlay(frame->overlay, &rect);
				}
			}
#else
			if (frame->surface != NULL) {
#ifdef USE_SDL_SHADOWSURFACE
				if (me->surface != NULL)
					AG_SDL_ShadowSurfaceFree(me->surface);
				me->surface = AG_SDL_ShadowSurface(frame->surface);
#else
				if (me->surface != NULL)
					AG_SurfaceFree(me->surface);
				me->surface = AG_SurfaceFromSDL(frame->surface);
#endif
				if (me->surface == NULL) {
					/* FIXME */
					break;
				}

				AG_Redraw(AGWIDGET(me));
			}
#endif
		} else {
			/* frame is skipped */
			DEBUG("skip frame: %lums late", sync - frame->pts);
		}

		frame->ready = 0;
		RR_INC(me->curVideoFrame, FFMPEGPLAYER_BUFSIZE);

		/* wake up buffer-fill thread */
		AG_CondSignal(&me->video_cond);
	}