#include "config.h" #include #include #include #include #include #include static int n_frames = 0; void write_png_file(char *fname, OggPlayRGBChannels *data) { Imlib_Image *image; /* for (i = 0; i < data->rgb_height; i++) { for (j = 0; j < data->rgb_width; j++) { char *ptr = data->ptro + i * data->rgb_width * 4 + j * 4; int *iptr = (int *)ptr; *iptr = (0xFF << 24) | ((((i >> 2) % 2) ? 0xFF : 0x00) << 16) | ((((j >> 2) % 2) ? 0xFF : 0x00) << 8); } }*/ FILE *f = fopen("out.rgb", "wb"); fwrite(data->ptro, data->rgb_width * data->rgb_height, 4, f); fclose(f); image = imlib_create_image_using_data(data->rgb_width, data->rgb_height, (unsigned int *)data->ptro); imlib_context_set_image(image); imlib_image_set_format("png"); imlib_save_image(fname); imlib_free_image_and_decache(); } #define CLAMP(v) ((v) > 255 ? 255 : (v) < 0 ? 0 : (v)) void yuv2rgb(OggPlayYUVChannels * yuv, OggPlayRGBChannels * rgb) { unsigned char * ptry = yuv->ptry; unsigned char * ptru = yuv->ptru; unsigned char * ptrv = yuv->ptrv; unsigned char * ptro = rgb->ptro; unsigned char * ptro2; int i, j; for (i = 0; i < yuv->y_height; i++) { ptro2 = ptro; for (j = 0; j < yuv->y_width; j += 2) { short pr, pg, pb; short r, g, b; //pr = ((128 + (ptrv[j/2] - 128) * 292) >> 8) - 16; /* 1.14 * 256 */ pr = (-41344 + ptrv[j/2] * 292) >> 8; //pg = ((128 - (ptru[j/2] - 128) * 101 - (ptrv[j/2] - 128) * 149) >> 8)-16; // /* 0.395 & 0.581 */ pg = (28032 - ptru[j/2] * 101 - ptrv[j/2] * 149) >> 8; //pb = ((128 + (ptru[j/2] - 128) * 520) >> 8) - 16; /* 2.032 */ pb = (-70528 + ptru[j/2] * 520) >> 8; r = ptry[j] + pr; g = ptry[j] + pg; b = ptry[j] + pb; *ptro2++ = CLAMP(b); *ptro2++ = CLAMP(g); *ptro2++ = CLAMP(r); *ptro2++ = 255; r = ptry[j + 1] + pr; g = ptry[j + 1] + pg; b = ptry[j + 1] + pb; *ptro2++ = CLAMP(b); *ptro2++ = CLAMP(g); *ptro2++ = CLAMP(r); *ptro2++ = 255; } ptry += yuv->y_width; if (i & 1) { ptru += yuv->uv_width; ptrv += yuv->uv_width; } ptro += rgb->rgb_width * 4; } } void dump_video_data (OggPlay * player, int track_num, OggPlayVideoData * video_data, int frame) { OggPlayYUVChannels from; OggPlayRGBChannels to; from.ptry = video_data->y; from.ptru = video_data->u; from.ptrv = video_data->v; oggplay_get_video_y_size(player, track_num, &(from.y_width), &(from.y_height)); oggplay_get_video_uv_size(player, track_num, &(from.uv_width), &(from.uv_height)); FILE *f = fopen("out.y", "wb"); fwrite(from.ptry, from.y_width * from.y_height, 1, f); fclose(f); printf("size: %dx%d %dx%d\n", from.y_width, from.y_height, from.uv_width, from.uv_height); to.ptro = malloc(from.y_width * from.y_height * 4); to.rgb_width = from.y_width; to.rgb_height = from.y_height; yuv2rgb(&from, &to); printf("now %dx%d\n", to.rgb_width, to.rgb_height); write_png_file("out.png", &to); //free(to.ptro); } int dump_streams_callback (OggPlay *player, int num_tracks, OggPlayCallbackInfo **track_info, void *user) { int i; //int j; OggPlayDataHeader ** headers; OggPlayVideoData * video_data; //OggPlayAudioData * audio_data; //int required; OggPlayDataType type; for (i = 0; i < num_tracks; i++) { type = oggplay_callback_info_get_type(track_info[i]); headers = oggplay_callback_info_get_headers(track_info[i]); switch (type) { case OGGPLAY_INACTIVE: break; case OGGPLAY_YUV_VIDEO: /* * there should only be one record */ if (oggplay_callback_info_get_required(track_info[i]) < 1) { printf("oops\n"); break; } video_data = oggplay_callback_info_get_video_data(headers[0]); dump_video_data(player, i, video_data, n_frames); exit(0); break; default: break; } } n_frames++; return 0; } int main (int argc, char * argv[]) { OggPlay * player; OggPlayReader * reader; int i; if (argc < 2) { printf ("please provide a filename\n"); exit (1); } if (strlen(argv[1]) > 7 && (strncmp(argv[1], "http://", 7) == 0)) { reader = oggplay_tcp_reader_new(argv[1], NULL, 80); } else { reader = oggplay_file_reader_new(argv[1]); } player = oggplay_open_with_reader(reader); if (player == NULL) { printf ("could not initialise oggplay with this file\n"); exit (1); } for (i = 0; i < oggplay_get_num_tracks (player); i++) { if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_THEORA) { oggplay_set_callback_num_frames (player, i, 1); } oggplay_set_track_active(player, i); } oggplay_set_data_callback(player, dump_streams_callback, NULL); oggplay_start_decoding(player); return 0; }