123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <daala/codec.h>
- #include <daala/daaladec.h>
- #include "SDL.h"
- #define ODS_NONE 0
- #define ODS_HEADER 1
- #define ODS_DATA 2
- typedef struct {
- SDL_Surface *screen;
- daala_info di;
- daala_comment dc;
- ogg_sync_state oy;
- FILE *input;
- char *input_path;
- ogg_stream_state os;
- daala_dec_ctx *dctx;
- SDL_Surface *surf;
- od_img img;
- int width;
- int height;
- int done;
- int od_state;
- int paused;
- int restart;
- int slow;
- int loop;
- int step;
- int valid;
- } player_example;
- static void img_to_rgb(SDL_Surface *surf, const od_img *img);
- int player_example_init(player_example *player);
- player_example *player_example_create();
- int player_example_clear(player_example *player);
- int player_example_free(player_example *player);
- int player_example_reset(player_example *player);
- int player_example_play(player_example *player);
- int player_example_restart(player_example *player);
- int player_example_open(player_example *player, char *path);
- int player_example_daala_stream_init(player_example *player, int serial) {
- int ret;
- if (player == NULL) return -1;
- ret = ogg_stream_init(&player->os, serial);
- if (ret != 0) return -1;
- daala_info_init(&player->di);
- daala_comment_init(&player->dc);
- player->od_state = ODS_HEADER;
- return 0;
- }
- int player_example_daala_stream_clear(player_example *player) {
- if (player == NULL) return -1;
- daala_info_clear(&player->di);
- daala_comment_clear(&player->dc);
- if (player->dctx != NULL) {
- daala_decode_free(player->dctx);
- player->dctx = NULL;
- }
- ogg_stream_clear(&player->os);
- player->od_state = ODS_NONE;
- return 0;
- }
- int player_example_init(player_example *player) {
- if (player == NULL) return -1;
- player->screen = NULL;
- player->surf = NULL;
- player->width = 0;
- player->height = 0;
- player->paused = 0;
- player->restart = 0;
- player->slow = 0;
- player->loop = 0;
- player->done = 0;
- player->step = 0;
- player->valid = 0;
- player->od_state = ODS_NONE;
- return 0;
- }
- int player_example_clear(player_example *player) {
- if (player == NULL) return -1;
- memset(player, 0, sizeof(player_example));
- return 0;
- }
- player_example *player_example_create() {
- int ret;
- player_example *player;
- player = malloc(sizeof(player_example));
- if (player == NULL) return NULL;
- ret = player_example_init(player);
- if (ret != 0) {
- free(player);
- return NULL;
- }
- return player;
- }
- int player_example_free(player_example *player) {
- int ret;
- if (player == NULL) return -1;
- ret = player_example_clear(player);
- if (ret == 0) {
- free(player);
- return 0;
- }
- return -1;
- }
- int player_example_reset(player_example *player) {
- int ret;
- if (player == NULL) return -1;
- ret = player_example_clear(player);
- if (ret != 0) return -1;
- ret = player_example_init(player);
- if (ret != 0) return -1;
- return 0;
- }
- int player_example_open_input(player_example *player, char *path) {
- if ((player == NULL) || ((path == NULL) || (path[0] == '\0'))) return -1;
- if ((path[0] == '-') && (path[1] == '\0')) {
- player->input = stdin;
- } else {
- player->input = fopen(path, "rb");
- }
- if (player->input == NULL) {
- player->input_path = "";
- return -1;
- }
- player->input_path = path;
- ogg_sync_init(&player->oy);
- return 0;
- }
- int player_example_close_input(player_example *player) {
- int ret;
- if (player == NULL) return -1;
- if ((player->input == stdin) || (player->input == NULL)) return -1;
- ret = fclose(player->input);
- player->input = NULL;
- ogg_sync_clear(&player->oy);
- if (ret != 0) return -1;
- return 0;
- }
- int player_example_input_restart(player_example *player) {
- int ret;
- if (player == NULL) return -1;
- if (player->input == stdin) return -1;
- ret = player_example_close_input(player);
- if (ret != 0) return -1;
- ret = player_example_open_input(player, player->input_path);
- return ret;
- }
- void player_example_handle_event(player_example *player, SDL_Event *event) {
- switch (event->type) {
- case SDL_QUIT:
- player->done = 1;
- break;
- case SDL_KEYDOWN:
- switch (event->key.keysym.sym) {
- case SDLK_q:
- player->done = 1;
- break;
- case SDLK_s:
- player->slow = !player->slow;
- break;
- case SDLK_l:
- player->loop = !player->loop;
- break;
- case SDLK_ESCAPE:
- player->done = 1;
- break;
- case SDLK_SPACE:
- player->paused = !player->paused;
- player->step = 0;
- break;
- case SDLK_PERIOD:
- player->step = 1;
- player->paused = 1;
- break;
- case SDLK_r:
- player->restart = 1;
- if (player->paused) {
- player->step = 1;
- }
- break;
- default:
- break;
- }
- }
- }
- void player_example_wait_user_input(player_example *player) {
- SDL_Event event;
- if (SDL_WaitEvent(&event)) {
- player_example_handle_event(player, &event);
- }
- }
- void player_example_check_user_input(player_example *player) {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- player_example_handle_event(player, &event);
- }
- }
- int player_example_play(player_example *player) {
- size_t bytes;
- char *buffer;
- int ret;
- ogg_page page;
- ogg_packet packet;
- daala_setup_info *dsi;
- dsi = NULL;
- while (!player->done) {
- while (ogg_sync_pageout(&player->oy, &page) != 1) {
- buffer = ogg_sync_buffer(&player->oy, 4096);
- if (buffer == NULL) return -1;
- bytes = fread(buffer, 1, 4096, player->input);
- if (bytes > 0) {
- ret = ogg_sync_wrote(&player->oy, bytes);
- if (ret != 0) return -1;
- } else {
- if (!player->valid) {
- fprintf(stderr, "Invalid Ogg\n");
- exit(1);
- }
- if (player->od_state != ODS_NONE) {
- ret = player_example_daala_stream_clear(player);
- if (ret != 0) return -1;
- }
- if (player->input == stdin) {
- return 0;
- }
- if (player->loop == 1) {
- player_example_input_restart(player);
- continue;
- }
- for (;;) {
- player_example_wait_user_input(player);
- if (player->restart) {
- ret = player_example_input_restart(player);
- player->restart = 0;
- if (ret != 0) return -1;
- break;
- }
- if (player->done) {
- return 0;
- }
- }
- }
- }
- if (ogg_page_bos(&page)) {
- ret = player_example_daala_stream_init(player,
- ogg_page_serialno(&page));
- if (ret != 0) return -1;
- }
- ret = ogg_stream_pagein(&player->os, &page);
- if (ret != 0) return -1;
- while (ogg_stream_packetout(&player->os, &packet) == 1) {
- switch (player->od_state) {
- case ODS_HEADER:
- ret = daala_decode_header_in(&player->di, &player->dc, &dsi, &packet);
- if (ret < 0) return -1;
- if (ret != 0) break;
- player->dctx = daala_decode_alloc(&player->di, dsi);
- if (player->dctx == NULL) return -1;
- daala_setup_free(dsi);
- dsi = NULL;
- player->od_state = ODS_DATA;
- case ODS_DATA:
- if ((player->screen == NULL)
- || (player->width != player->di.pic_width)
- || (player->height != player->di.pic_height)) {
- player->width = player->di.pic_width;
- player->height = player->di.pic_height;
- player->screen = SDL_SetVideoMode(player->width, player->height, 24,
- SDL_HWSURFACE | SDL_DOUBLEBUF);
- if (player->screen == NULL) return -1;
- player->surf = SDL_GetVideoSurface();
- if (player->surf == NULL) return -1;
- }
- ret = daala_decode_packet_in(player->dctx, &player->img, &packet);
- if (ret != 0) return -1;
- player->valid = 1;
- if ((player->slow) && (!player->step)) {
- SDL_Delay(420);
- }
- player_example_check_user_input(player);
- while ((player->paused) && (!player->done)) {
- if (player->restart) {
- break;
- }
- if (player->step) {
- player->step = 0;
- break;
- }
- player_example_wait_user_input(player);
- }
- if ((!player->restart) && (!player->done)) {
- SDL_LockSurface(player->surf);
- img_to_rgb(player->surf, &player->img);
- SDL_UnlockSurface(player->surf);
- SDL_Flip(player->screen);
- }
- }
- }
- if ((player->restart) || (ogg_page_eos(&page))) {
- ret = player_example_daala_stream_clear(player);
- if (ret != 0) return -1;
- }
- if (player->restart) {
- ret = player_example_input_restart(player);
- player->restart = 0;
- if (ret != 0) return -1;
- }
- }
- if (player->od_state != ODS_NONE) {
- ret = player_example_daala_stream_clear(player);
- if (ret != 0) return -1;
- }
- return 0;
- }
- int main(int argc, char *argv[]) {
- int ret;
- char *input;
- int start_paused;
- player_example *player;
- daala_log_init();
- if ((argc == 3) && (memcmp(argv[1], "-p", 2) == 0)) {
- start_paused = 1;
- input = argv[2];
- } else {
- if ((argc != 2) || ((argc == 2)
- && ((memcmp(argv[1], "-h", 2) == 0)
- || (memcmp(argv[1] + 1, "-h", 2) == 0)))) {
- fprintf(stderr, "usage: %s input.ogg\n%s\n", argv[0],
- "\nProgram Options:\n-p to start paused\n- to read from stdin\n\n"
- "Playback Control: \n"
- "r to restart\nl to loop\ns for slow\n. to step\nspace to pause\n"
- "q to quit");
- exit(1);
- }
- start_paused = 0;
- input = argv[1];
- }
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- fprintf(stderr, "error: unable to init SDL\n");
- exit(1);
- }
- atexit(SDL_Quit);
- SDL_EnableKeyRepeat(222, 100);
- player = player_example_create();
- if (player == NULL) {
- fprintf(stderr, "player example error: create player\n");
- return -1;
- }
- ret = player_example_open_input(player, input);
- if (ret != 0) {
- fprintf(stderr, "player example error: could not open: %s\n", input);
- player_example_free(player);
- return -1;
- }
- if (start_paused == 1) {
- player->step = 1;
- player->paused = 1;
- }
- ret = player_example_play(player);
- if (ret != 0) {
- fprintf(stderr, "player example error: playback error\n");
- exit(1);
- }
- ret = player_example_free(player);
- return ret;
- }
- #define OD_MINI(_a,_b) ((_a)<(_b)?(_a):(_b))
- #define OD_MAXI(_a,_b) ((_a)>(_b)?(_a):(_b))
- #define OD_CLAMPI(_a,_b,_c) (OD_MAXI(_a,OD_MINI(_b,_c)))
- #define OD_SIGNMASK(_a) (-((_a)<0))
- #define OD_FLIPSIGNI(_a,_b) (((_a)+OD_SIGNMASK(_b))^OD_SIGNMASK(_b))
- #define OD_DIV_ROUND(_x,_y) (((_x)+OD_FLIPSIGNI((_y)>>1,_x))/(_y))
- #define OD_CLAMP255(_x) ((unsigned char)((((_x)<0)-1)&((_x)|-((_x)>255))))
- void img_to_rgb(SDL_Surface *surf, const od_img *img) {
- unsigned char *y_row;
- unsigned char *cb_row;
- unsigned char *cr_row;
- unsigned char *y;
- unsigned char *cb;
- unsigned char *cr;
- int y_stride;
- int cb_stride;
- int cr_stride;
- int width;
- int height;
- int xdec;
- int ydec;
- int i;
- int j;
- unsigned char *pixels;
- int pitch;
- pixels = (unsigned char *)surf->pixels;
- pitch = surf->pitch;
- width = img->width;
- height = img->height;
-
- xdec = img->planes[1].xdec;
- ydec = img->planes[1].ydec;
- y_stride = img->planes[0].ystride;
- cb_stride = img->planes[1].ystride;
- cr_stride = img->planes[2].ystride;
- y_row = img->planes[0].data;
- cb_row = img->planes[1].data;
- cr_row = img->planes[2].data;
-
- for (j = 0; j < height; j++) {
- int dc;
- y = y_row;
- cb = cb_row;
- cr = cr_row;
- for (i = 0; i < 3 * width;) {
- int64_t yval;
- int64_t cbval;
- int64_t crval;
- unsigned rval;
- unsigned gval;
- unsigned bval;
- yval=*y-16;
- cbval=*cb-128;
- crval=*cr-128;
-
- rval=OD_CLAMPI(0,(int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval+4490222169144LL*crval,9745792000LL),65535);
- gval=OD_CLAMPI(0,(int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval-534117096223LL*cbval-1334761232047LL*crval,
- 9745792000LL),65535);
- bval=OD_CLAMPI(0,(int32_t)OD_DIV_ROUND(
- 2916394880000LL*yval+5290866304968LL*cbval,9745792000LL),65535);
- *(pixels + pitch*j + i++)=(unsigned char)(bval>>8);
- *(pixels + pitch*j + i++)=(unsigned char)(gval>>8);
- *(pixels + pitch*j + i++)=(unsigned char)(rval>>8);
- dc = ((y - y_row) & 1) | (1 - xdec);
- y++;
- cb += dc;
- cr += dc;
- }
- y_row += y_stride;
- dc = -((j & 1) | (1 - ydec));
- cb_row += dc & cb_stride;
- cr_row += dc & cr_stride;
- }
- }
|