static void process_download(struct server_attr *attr) { int fd; unsigned int length, n; char str[BUFSZ]; char filename[NAME_MAX + 1]; download_next: /* Format: | uint file-length | uint file-name-length | file-name */ length = *((int *)attr->data); n = *((int *)(attr->data + sizeof(length))); strncpy(filename, (attr->data + sizeof(length) * 2), n); *(filename + n) = 0; create_download_dir(filename); /* create directory if necessary */ /* Overwrite exist file */ fd = open(filename, O_WRONLY | O_CREAT, DEFAULT_DL_FILE_MODE); if (fd == -1) { err_msg(errno, "Error for open %s", filename); return; } SET_PROGRESS_DOWNLOAD(str, filename, length); n = 0; while (n < length) { recv_response(attr); writen(fd, attr->data, attr->resp.len); n += attr->resp.len; PRINT_PROGRESS(str, length, n); } printf("\n"); close(fd); /* Confirm does recived the RESP_DATA_FINISH flag */ recv_response(attr); if (attr->resp.code != RESP_DATA_FINISH) goto download_next; }
int main (int argc, char *argv[]) { GOptionGroup *options; GOptionContext *context; GError *err = NULL; GdkPixbuf *pixbuf; const char *input, *output; ThumbApp app; context = g_option_context_new ("Thumbnail movies"); options = gst_init_get_option_group (); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, options); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { g_print ("couldn't parse command-line options: %s\n", err->message); g_error_free (err); return 1; } #ifdef G_OS_UNIX if (time_limit != FALSE) { errno = 0; if (nice (20) != 20 && errno != 0) g_warning ("Couldn't change nice value of process."); } #endif if (print_progress) { fcntl (fileno (stdout), F_SETFL, O_NONBLOCK); setbuf (stdout, NULL); } if (g_fatal_warnings) { GLogLevelFlags fatal_mask; fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); } if (raw_output == FALSE && output_size == -1) output_size = DEFAULT_OUTPUT_SIZE; if (filenames == NULL || g_strv_length (filenames) != 2 || (second_index != -1 && gallery != -1) || (print_progress == TRUE && verbose == TRUE)) { char *help; help = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", help); g_free (help); return 1; } input = filenames[0]; output = filenames[1]; PROGRESS_DEBUG("Initialised libraries, about to create video widget"); PRINT_PROGRESS (2.0); app.input = input; app.output = output; thumb_app_setup_play (&app); thumb_app_set_filename (&app); PROGRESS_DEBUG("Video widget created"); PRINT_PROGRESS (6.0); if (time_limit != FALSE) xplayer_resources_monitor_start (input, 0); PROGRESS_DEBUG("About to open video file"); if (thumb_app_start (&app) == FALSE) { g_print ("xplayer-video-thumbnailer couldn't open file '%s'\n", input); exit (1); } thumb_app_set_error_handler (&app); /* We don't need covers when we're in gallery mode */ if (gallery == -1) thumb_app_check_for_cover (&app); if (thumb_app_get_has_video (&app) == FALSE) { PROGRESS_DEBUG ("xplayer-video-thumbnailer couldn't find a video track in '%s'\n", input); exit (1); } thumb_app_set_duration (&app); PROGRESS_DEBUG("Opened video file: '%s'", input); PRINT_PROGRESS (10.0); if (gallery == -1) { /* If the user has told us to use a frame at a specific second * into the video, just use that frame no matter how boring it * is */ if (second_index != -1) { assert_duration (&app); pixbuf = capture_frame_at_time (&app, second_index * 1000); } else { pixbuf = capture_interesting_frame (&app); } PRINT_PROGRESS (90.0); } else { assert_duration (&app); /* We're producing a gallery of screenshots from throughout the file */ pixbuf = create_gallery (&app); } /* Cleanup */ xplayer_resources_monitor_stop (); thumb_app_cleanup (&app); PRINT_PROGRESS (92.0); if (pixbuf == NULL) { g_print ("xplayer-video-thumbnailer couldn't get a picture from '%s'\n", input); exit (1); } PROGRESS_DEBUG("Saving captured screenshot"); save_pixbuf (pixbuf, output, input, output_size, FALSE); g_object_unref (pixbuf); PRINT_PROGRESS (100.0); return 0; }
static GdkPixbuf * create_gallery (ThumbApp *app) { GdkPixbuf *screenshot, *pixbuf = NULL; cairo_t *cr; cairo_surface_t *surface; PangoLayout *layout; PangoFontDescription *font_desc; gint64 stream_length, screenshot_interval, pos; guint columns = 3, rows, current_column, current_row, x, y; gint screenshot_width = 0, screenshot_height = 0, x_padding = 0, y_padding = 0; gfloat scale = 1.0; gchar *header_text, *duration_text, *filename; /* Calculate how many screenshots we're going to take */ stream_length = app->duration; /* As a default, we have one screenshot per minute of stream, * but adjusted so we don't have any gaps in the resulting gallery. */ if (gallery == 0) { gallery = stream_length / 60000; while (gallery % 3 != 0 && gallery % 4 != 0 && gallery % 5 != 0) { gallery++; } } if (gallery < GALLERY_MIN) gallery = GALLERY_MIN; if (gallery > GALLERY_MAX) gallery = GALLERY_MAX; screenshot_interval = stream_length / gallery; /* Put a lower bound on the screenshot interval so we can't enter an infinite loop below */ if (screenshot_interval == 0) screenshot_interval = 1; PROGRESS_DEBUG ("Producing gallery of %u screenshots, taken at %" G_GINT64_FORMAT " millisecond intervals throughout a %" G_GINT64_FORMAT " millisecond-long stream.", gallery, screenshot_interval, stream_length); /* Calculate how to arrange the screenshots so we don't get ones orphaned on the last row. * At this point, only deal with arrangements of 3, 4 or 5 columns. */ y = G_MAXUINT; for (x = 3; x <= 5; x++) { if (gallery % x == 0 || x - gallery % x < y) { y = x - gallery % x; columns = x; /* Have we found an optimal solution already? */ if (y == x) break; } } rows = ceil ((gfloat) gallery / (gfloat) columns); PROGRESS_DEBUG ("Outputting as %u rows and %u columns.", rows, columns); /* Take the screenshots and composite them into a pixbuf */ current_column = current_row = x = y = 0; for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) { if (pos == stream_length) screenshot = capture_frame_at_time (app, pos - 1); else screenshot = capture_frame_at_time (app, pos); if (pixbuf == NULL) { screenshot_width = gdk_pixbuf_get_width (screenshot); screenshot_height = gdk_pixbuf_get_height (screenshot); /* Calculate a scaling factor so that screenshot_width -> output_size */ scale = (float) output_size / (float) screenshot_width; x_padding = x = MAX (output_size * 0.05, 1); y_padding = y = MAX (scale * screenshot_height * 0.05, 1); PROGRESS_DEBUG ("Scaling each screenshot by %f.", scale); /* Create our massive pixbuf */ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, columns * output_size + (columns + 1) * x_padding, (guint) (rows * scale * screenshot_height + (rows + 1) * y_padding)); gdk_pixbuf_fill (pixbuf, 0x000000ff); PROGRESS_DEBUG ("Created output pixbuf (%ux%u).", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); } /* Composite the screenshot into our gallery */ gdk_pixbuf_composite (screenshot, pixbuf, x, y, output_size, scale * screenshot_height, (gdouble) x, (gdouble) y, scale, scale, GDK_INTERP_BILINEAR, 255); g_object_unref (screenshot); PROGRESS_DEBUG ("Composited screenshot from %" G_GINT64_FORMAT " milliseconds (address %u) at (%u,%u).", pos, GPOINTER_TO_UINT (screenshot), x, y); /* We print progress in the range 10% (MIN_PROGRESS) to 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0 */ PRINT_PROGRESS (MIN_PROGRESS + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0)); current_column = (current_column + 1) % columns; x += output_size + x_padding; if (current_column == 0) { x = x_padding; y += scale * screenshot_height + y_padding; current_row++; } } PROGRESS_DEBUG ("Converting pixbuf to a Cairo surface."); /* Load the pixbuf into a Cairo surface and overlay the text. The height is the height of * the gallery plus the necessary height for 3 lines of header (at ~18px each), plus some * extra padding. */ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf) + GALLERY_HEADER_HEIGHT + y_padding); cr = cairo_create (surface); cairo_surface_destroy (surface); /* First, copy across the gallery pixbuf */ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0.0, GALLERY_HEADER_HEIGHT + y_padding); cairo_rectangle (cr, 0.0, GALLERY_HEADER_HEIGHT + y_padding, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); cairo_fill (cr); g_object_unref (pixbuf); /* Build the header information */ duration_text = xplayer_time_to_string (stream_length); filename = NULL; if (strstr (app->input, "://")) { char *local; local = g_filename_from_uri (app->input, NULL, NULL); filename = g_path_get_basename (local); g_free (local); } if (filename == NULL) filename = g_path_get_basename (app->input); /* Translators: The first string is "Filename" (as translated); the second is an actual filename. The third string is "Resolution" (as translated); the fourth and fifth are screenshot height and width, respectively. The sixth string is "Duration" (as translated); the seventh is the movie duration in words. */ header_text = g_markup_printf_escaped (_("<b>%s</b>: %s\n<b>%s</b>: %d\303\227%d\n<b>%s</b>: %s"), _("Filename"), filename, _("Resolution"), screenshot_width, screenshot_height, _("Duration"), duration_text); g_free (duration_text); g_free (filename); PROGRESS_DEBUG ("Writing header text with Pango."); /* Write out some header information */ layout = pango_cairo_create_layout (cr); font_desc = pango_font_description_from_string ("Sans 18px"); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); pango_layout_set_markup (layout, header_text, -1); g_free (header_text); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_move_to (cr, (gdouble) x_padding, (gdouble) y_padding); pango_cairo_show_layout (cr, layout); /* Go through each screenshot and write its timestamp */ current_column = current_row = 0; x = x_padding + output_size; y = y_padding * 2 + GALLERY_HEADER_HEIGHT + scale * screenshot_height; font_desc = pango_font_description_from_string ("Sans 10px"); pango_layout_set_font_description (layout, font_desc); pango_font_description_free (font_desc); PROGRESS_DEBUG ("Writing screenshot timestamps with Pango."); for (pos = screenshot_interval; pos <= stream_length; pos += screenshot_interval) { gchar *timestamp_text; gint layout_width, layout_height; timestamp_text = xplayer_time_to_string (pos); pango_layout_set_text (layout, timestamp_text, -1); pango_layout_get_pixel_size (layout, &layout_width, &layout_height); /* Display the timestamp in the bottom-right corner of the current screenshot */ cairo_move_to (cr, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height); /* We have to stroke the text so it's visible against screenshots of the same * foreground color. */ pango_cairo_layout_path (cr, layout); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ cairo_stroke_preserve (cr); cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_fill (cr); PROGRESS_DEBUG ("Writing timestamp \"%s\" at (%f,%f).", timestamp_text, x - layout_width - 0.02 * output_size, y - layout_height - 0.02 * scale * screenshot_height); /* We print progress in the range 50% (MAX_PROGRESS - MIN_PROGRESS) / 2.0) to 90% (MAX_PROGRESS) */ PRINT_PROGRESS (MIN_PROGRESS + (MAX_PROGRESS - MIN_PROGRESS) / 2.0 + (current_row * columns + current_column) * (((MAX_PROGRESS - MIN_PROGRESS) / gallery) / 2.0)); g_free (timestamp_text); current_column = (current_column + 1) % columns; x += output_size + x_padding; if (current_column == 0) { x = x_padding + output_size; y += scale * screenshot_height + y_padding; current_row++; } } g_object_unref (layout); PROGRESS_DEBUG ("Converting Cairo surface back to pixbuf."); /* Create a new pixbuf from the Cairo context */ pixbuf = cairo_surface_to_pixbuf (cairo_get_target (cr)); cairo_destroy (cr); return pixbuf; }
int main (int argc, char *argv[]) { GOptionGroup *options; GOptionContext *context; GError *err = NULL; BaconVideoWidget *bvw; GdkPixbuf *pixbuf; const char *input, *output; callback_data data; g_thread_init (NULL); context = g_option_context_new ("Thumbnail movies"); options = bacon_video_widget_get_option_group (); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, options); #ifndef THUMB_DEBUG g_type_init (); #else g_option_context_add_group (context, gtk_get_option_group (TRUE)); #endif if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { g_print ("couldn't parse command-line options: %s\n", err->message); g_error_free (err); return 1; } #ifdef G_OS_UNIX if (time_limit != FALSE) { errno = 0; if (nice (20) != 20 && errno != 0) g_warning ("Couldn't change nice value of process."); } #endif if (print_progress) { fcntl (fileno (stdout), F_SETFL, O_NONBLOCK); setbuf (stdout, NULL); } if (g_fatal_warnings) { GLogLevelFlags fatal_mask; fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); } if (raw_output == FALSE && output_size == -1) output_size = DEFAULT_OUTPUT_SIZE; if (filenames == NULL || g_strv_length (filenames) != 2 || (second_index != -1 && gallery != -1) || (print_progress == TRUE && verbose == TRUE)) { char *help; help = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", help); g_free (help); return 1; } input = filenames[0]; output = filenames[1]; PROGRESS_DEBUG("Initialised libraries, about to create video widget"); PRINT_PROGRESS (2.0); bvw = BACON_VIDEO_WIDGET (bacon_video_widget_new (-1, -1, BVW_USE_TYPE_CAPTURE, &err)); if (err != NULL) { g_print ("totem-video-thumbnailer couldn't create the video " "widget.\nReason: %s.\n", err->message); g_error_free (err); exit (1); } data.input = input; data.output = output; g_signal_connect (G_OBJECT (bvw), "got-metadata", G_CALLBACK (on_got_metadata_event), &data); PROGRESS_DEBUG("Video widget created"); PRINT_PROGRESS (6.0); if (time_limit != FALSE) totem_resources_monitor_start (input, 0); PROGRESS_DEBUG("About to open video file"); if (bacon_video_widget_open (bvw, input, NULL, &err) == FALSE) { g_print ("totem-video-thumbnailer couldn't open file '%s'\n" "Reason: %s.\n", input, err->message); g_error_free (err); exit (1); } PROGRESS_DEBUG("Opened video file: '%s'", input); PRINT_PROGRESS (10.0); if (gallery == -1) { /* If the user has told us to use a frame at a specific second * into the video, just use that frame no matter how boring it * is */ if (second_index != -1) pixbuf = capture_frame_at_time (bvw, input, output, second_index); else pixbuf = capture_interesting_frame (bvw, input, output); PRINT_PROGRESS (90.0); } else { /* We're producing a gallery of screenshots from throughout the file */ pixbuf = create_gallery (bvw, input, output); } /* Cleanup */ bacon_video_widget_close (bvw); totem_resources_monitor_stop (); gtk_widget_destroy (GTK_WIDGET (bvw)); PRINT_PROGRESS (92.0); if (pixbuf == NULL) { g_print ("totem-video-thumbnailer couldn't get a picture from " "'%s'\n", input); exit (1); } PROGRESS_DEBUG("Saving captured screenshot"); save_pixbuf (pixbuf, output, input, output_size, FALSE); g_object_unref (pixbuf); PRINT_PROGRESS (100.0); return 0; }
/* Download the file which pointed by "pathname" */ static int transmit(struct server_attr *attr, char *pathname, int dir_name_length, int flags) { int fd; unsigned int length, n; char *p; char str[BUFSZ]; if ((fd = open(pathname, O_RDONLY)) == -1) { err_msg(errno, "open"); return -1; } debug("upload: %s", pathname); debug("Transmit: %s", pathname); /* File's length */ attr->req.len = 0; length = lseek(fd, 0, SEEK_END); attr->req.code = RESP_UPLOAD; memcpy(attr->data, &length, sizeof(length)); attr->req.len += sizeof(length); if (!flags) { /* The pathname include filename only. */ n = strlen(pathname); p = pathname; } else if (flags == UPLOAD_INCLUDE_DIR_NAME) { /* Setting the UPLOAD_INCLUDE_DIR_NAME flag */ p = brevity_name(pathname, dir_name_length, flags); n = strlen(p); } printf("%s, %d\n", pathname, dir_name_length); /* Filename's length */ memcpy(attr->data + attr->req.len, &n, sizeof(n)); attr->req.len += sizeof(n); /* Filename */ memcpy(attr->data + attr->req.len, p, n); attr->req.len += n; send_request(attr); SET_PROGRESS_UPLOAD(str, p, length); /* Send data to server*/ n = 0; lseek(fd, 0, SEEK_SET); while ((attr->req.len = read(fd, attr->data, BUFSZ - 1)) > 0) { send_request(attr); n += attr->req.len; PRINT_PROGRESS(str, length, n); } if (attr->resp.len == -1) { err_msg(errno, "Upload occur error"); return -1; } printf("\n"); close(fd); return 0; }
int main (int argc, char *argv[]) { GOptionGroup *options; GOptionContext *context; GError *err = NULL; GdkPixbuf *pixbuf; const char *input, *output; ThumbApp app; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); context = g_option_context_new ("Thumbnail movies"); options = gst_init_get_option_group (); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_group (context, options); if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { g_print ("couldn't parse command-line options: %s\n", err->message); g_error_free (err); return 1; } fcntl (fileno (stdout), F_SETFL, O_NONBLOCK); setbuf (stdout, NULL); if (raw_output == FALSE && output_size == -1) output_size = DEFAULT_OUTPUT_SIZE; if (filenames == NULL || g_strv_length (filenames) != 2 || (second_index != -1 && gallery != -1)) { char *help; help = g_option_context_get_help (context, FALSE, NULL); g_print ("%s", help); g_free (help); return 1; } input = filenames[0]; output = filenames[1]; g_debug("Initialised libraries, about to create video widget"); PRINT_PROGRESS (2.0); app.input = input; app.output = output; thumb_app_setup_play (&app); thumb_app_set_filename (&app); g_debug("Video widget created"); PRINT_PROGRESS (6.0); g_debug("About to open video file"); if (thumb_app_start (&app) == FALSE) { g_print ("totem-video-thumbnailer couldn't open file '%s'\n", input); exit (1); } thumb_app_set_error_handler (&app); if (thumb_app_get_has_video (&app) == FALSE) { g_debug ("totem-video-thumbnailer couldn't find a video track in '%s'\n", input); exit (1); } thumb_app_set_duration (&app); g_debug("Opened video file: '%s'", input); PRINT_PROGRESS (10.0); assert_duration (&app); /* We're producing a gallery of screenshots from throughout the file */ pixbuf = create_gallery (&app); /* Cleanup */ thumb_app_cleanup (&app); PRINT_PROGRESS (92.0); if (pixbuf == NULL) { g_print ("totem-video-thumbnailer couldn't get a picture from '%s'\n", input); exit (1); } g_debug("Saving captured screenshot to %s", output); save_pixbuf (pixbuf, output, input, output_size, FALSE); g_object_unref (pixbuf); PRINT_PROGRESS (100.0); return 0; }
int main(int argc, const char * argv[]) { setbuf (stdout, NULL); #if TARGET_OS_MAC { thread_extended_policy_data_t theFixedPolicy; theFixedPolicy.timeshare = false; // set to true for a non-fixed thread thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); // We keep a reference to the spawning thread's priority around (initialized in the constructor), // and set the importance of the child thread relative to the spawning thread's priority. thread_precedence_policy_data_t thePrecedencePolicy; thePrecedencePolicy.importance = 63 - 36; thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); } #endif // These are the variables that are set up from the input parsing char* srcFilePath = NULL; char* destFilePath = NULL; char* auPresetFile = NULL; bool shortMemoryProfile = false; OSType manu, subType, type = 0; int userSetFrames = -1; for (int i = 1; i < argc; ++i) { if (strcmp (argv[i], "-au") == 0) { if ( (i + 3) < argc ) { StrToOSType (argv[i + 1], type); StrToOSType (argv[i + 2], subType); StrToOSType (argv[i + 3], manu); i += 3; } else { printf ("Which Audio Unit:\n%s", usageStr); exit(1); } } else if (strcmp (argv[i], "-i") == 0) { srcFilePath = const_cast<char*>(argv[++i]); } else if (strcmp (argv[i], "-o") == 0) { destFilePath = const_cast<char*>(argv[++i]); } else if (strcmp (argv[i], "-p") == 0) { auPresetFile = const_cast<char*>(argv[++i]); } else if (strcmp (argv[i], "-m") == 0) { shortMemoryProfile = true; } else if (strcmp (argv[i], "-f") == 0) { sscanf(argv[++i], "%d", &userSetFrames); } else { printf ("%s\n", usageStr); exit(1); } } if (!type || !srcFilePath) { printf ("%s\n", usageStr); exit(1); } if (!destFilePath) { if (!shortMemoryProfile) { printf ("%s\n", usageStr); exit(1); } } // delete pre-existing output file if (!shortMemoryProfile) { FSRef destFSRef; if (FSPathMakeRef((UInt8 *)destFilePath, &destFSRef, NULL) == noErr) { // output file exists - delete it if (FSDeleteObject(&destFSRef)) { printf ("Cannot Delete Output File\n"); exit(1); } } } CAComponentDescription desc(type, subType, manu); CFPropertyListRef presetDict = ReadPresetFromPresetFile(auPresetFile); // the num of frames to use when processing the file with the Render call UInt32 maxFramesToUse = shortMemoryProfile ? 512 : 32768; // not set from command line if (userSetFrames > 0) { maxFramesToUse = userSetFrames; } // in some settings (for instance a delay with 100% feedback) tail time is essentially infinite // so you should safeguard the final OL render stage (post process) which is aimed at pulling the tail through // if you want to bypass this completely, just set this to zero. Float64 maxTailTimeSecs = 10.; #pragma mark - #pragma mark __ The driving code #pragma mark - try { CAComponent comp(desc); // CAAUProcessor's constructor throws... so make sure the component is valid if (comp.IsValid() == false) { printf ("Can't Find Component\n"); desc.Print(); exit(1); } CAAUProcessor processor(comp); processor.AU().Print(); CAAudioFile srcFile; CAAudioFile destFile; srcFile.Open(srcFilePath); CAStreamBasicDescription procFormat (srcFile.GetFileDataFormat()); procFormat.SetCanonical (srcFile.GetFileDataFormat().NumberChannels(), false); printf ("Processing Format:\n\t"); procFormat.Print(); if (!shortMemoryProfile) { FSRef parentDir; CFStringRef filename; PosixPathToParentFSRefAndName(destFilePath, parentDir, filename); destFile.CreateNew (parentDir, filename, 'AIFF', srcFile.GetFileDataFormat()); destFile.SetClientFormat (procFormat); } srcFile.SetClientFormat (procFormat); AUOutputBL outputList(procFormat); ReadBuffer* readBuf = NULL; #if !CAAF_USE_EXTAUDIOFILE UInt64 numInputSamples = srcFile.GetNumberPackets(); #else UInt64 numInputSamples = srcFile.GetNumberFrames(); #endif if (shortMemoryProfile) { readBuf = new ReadBuffer; readBuf->readData = new AUOutputBL(procFormat); readBuf->readFrames = 0; UInt32 numFrames = UInt32(procFormat.mSampleRate / 2); readBuf->readData->Allocate (numFrames); // half a second of audio data readBuf->readData->Prepare(); // half a second of audio data // read 1/2 second of audio into this read buffer srcFile.Read (numFrames, readBuf->readData->ABL()); sInputCallback.inputProc = MemoryInputCallback; sInputCallback.inputProcRefCon = readBuf; numInputSamples = numFrames; } else { if (desc.IsFConv()) { maxFramesToUse = userSetFrames == -1 ? 512 : maxFramesToUse; // some format converter's can call you several times in small granularities // so you can't use a large buffer to render or you won't return all of the input data // this also lessens the final difference between what you should get and what you do // converter units *really* should have a version that are offline AU's to // handle this for you. sInputCallback.inputProc = FConvInputCallback; } else sInputCallback.inputProc = InputCallback; sInputCallback.inputProcRefCon = &srcFile; } OSStatus result; require_noerr (result = processor.EstablishInputCallback (sInputCallback), home); require_noerr (result = processor.SetMaxFramesPerRender (maxFramesToUse), home); processor.SetMaxTailTime (maxTailTimeSecs); require_noerr (result = processor.Initialize (procFormat, numInputSamples), home); if (presetDict) { require_noerr (result = processor.SetAUPreset (presetDict), home); CFRelease (presetDict); } // this does ALL of the preflighting.. could be specialise for an OfflineAU type // to do this piecemeal and do a progress bar by using the OfflineAUPreflight method require_noerr (result = processor.Preflight (), home); bool isDone; isDone = false; bool needsPostProcessing; bool isSilence; UInt32 numFrames; numFrames = processor.MaxFramesPerRender(); #if CA_AU_PROFILE_TIME sReadTime = 0; sRenderTime = 0; #endif PRINT_MARKS(); // this is the render loop while (!isDone) { #if CA_AU_PROFILE_TIME UInt64 now = CAHostTimeBase::GetTheCurrentTime(); #endif outputList.Prepare(); // have to do this every time... require_noerr (result = processor.Render (outputList.ABL(), numFrames, isSilence, &isDone, &needsPostProcessing), home); #if CA_AU_PROFILE_TIME sRenderTime += (CAHostTimeBase::GetTheCurrentTime() - now); #endif if (!shortMemoryProfile) PRINT_PROGRESS(processor.GetOLPercentComplete()); else PRINT_PROGRESS(((processor.SampleTime() / numInputSamples) * 100.)); if (numFrames && !shortMemoryProfile) destFile.Write (numFrames, outputList.ABL()); } // this is the postprocessing if needed if (!shortMemoryProfile && needsPostProcessing) { isDone = false; numFrames = processor.MaxFramesPerRender(); while (!isDone) { outputList.Prepare(); // have to do this every time... #if CA_AU_PROFILE_TIME UInt64 now = CAHostTimeBase::GetTheCurrentTime(); #endif require_noerr (result = processor.PostProcess (outputList.ABL(), numFrames, isSilence, isDone), home); #if CA_AU_PROFILE_TIME sRenderTime += (CAHostTimeBase::GetTheCurrentTime() - now); #endif PRINT_PROGRESS(processor.GetOLPercentComplete()); if (numFrames && !shortMemoryProfile) destFile.Write (numFrames, outputList.ABL()); } } printf ("\n"); home: if (result) { printf ("Exit with bad result:%ld\n", result); exit(result); } if (readBuf) { delete readBuf->readData; delete readBuf; } #if CA_AU_PROFILE_TIME if (!shortMemoryProfile) { // this flushes any remaing data to be written to the disk. // the source file is closed in its destructor of course destFile.Close(); // open the file again, to get stats about it for profiling destFile.Open(destFilePath); } SInt64 numWritten; if (shortMemoryProfile) numWritten = 0; else { #if !CAAF_USE_EXTAUDIOFILE numWritten = destFile.GetNumberPackets(); #else numWritten = destFile.GetNumberFrames(); #endif } printf ("Read File Time:%.2f secs for %lld packets (%.1f secs), wrote %lld packets\n", (CAHostTimeBase::ConvertToNanos (sReadTime) / 1.0e9), numInputSamples, (numInputSamples / procFormat.mSampleRate), numWritten); if (!shortMemoryProfile) { #if !CAAF_USE_EXTAUDIOFILE UInt64 numOutputSamples = destFile.GetNumberPackets(); #else UInt64 numOutputSamples = destFile.GetNumberFrames(); #endif if (numOutputSamples == numInputSamples) { printf ("\tWrote the same number of packets as read\n"); } else { bool expectationMet = !desc.IsOffline(); // we don't have any expectations for offline AU's if (processor.LatencySampleCount() || processor.TailSampleCount()) { if (numOutputSamples - numInputSamples == processor.TailSampleCount()) expectationMet = true; if (expectationMet) printf ("Correctly wrote \'Read Size + Tail\'. "); printf ("AU reports (samples): %ld latency, %ld tail\n", processor.LatencySampleCount(), processor.TailSampleCount()); } if (expectationMet == false) { if (numOutputSamples > numInputSamples) { printf ("\tWrote %lld packets (%.2f secs) more than read\n", (numOutputSamples - numInputSamples), ((numOutputSamples - numInputSamples) / procFormat.mSampleRate)); } else { printf ("\tRead %lld packets (%.2f secs) more than wrote\n", (numInputSamples - numOutputSamples), ((numInputSamples - numOutputSamples) / procFormat.mSampleRate)); } } } } Float64 renderTimeSecs = CAHostTimeBase::ConvertToNanos (sRenderTime - sReadTime) / 1.0e9; printf ("Total Render Time:%.2f secs, using render slice size of %ld frames\n", renderTimeSecs, maxFramesToUse); Float64 cpuUsage; if (shortMemoryProfile) cpuUsage = (renderTimeSecs / 0.5) * 100.; else cpuUsage = (renderTimeSecs / (numInputSamples / procFormat.mSampleRate)) * 100.; printf ("CPU Usage for Render Time:%.2f%%\n", cpuUsage); CFStringRef str = comp.GetCompName(); UInt32 compNameLen = CFStringGetLength (str); CFStringRef presetName = NULL; if (auPresetFile) { CFPropertyListRef dict; if (processor.AU().GetAUPreset (dict) == noErr) { presetName = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)dict, CFSTR("name")); CFRelease (dict); } } UInt32 presetLen = presetName ? CFStringGetLength(presetName) : 0; char* cstr = (char*)malloc (compNameLen + presetLen + 2 + 1); CFStringGetCString (str, cstr, (CFStringGetLength (str) + 1), kCFStringEncodingASCII); if (presetName) { cstr[compNameLen] = ':'; cstr[compNameLen+1] = ':'; CFStringGetCString (presetName, cstr + compNameLen + 2, (CFStringGetLength (presetName) + 1), kCFStringEncodingASCII); } PerfResult("AudioUnitProcess", EndianU32_NtoB(comp.Desc().componentSubType), cstr, cpuUsage, "%realtime"); free (cstr); #endif } catch (CAXException &e) { char buf[256]; printf("Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); exit(1); } catch (...) { printf("An unknown error occurred\n"); exit(1); } return 0; }
int UnRUU(const char *path_ruu_exe_name, const char *path_out) { PRINT_TITLE("Extracting rom.zip from %s", get_basename(path_ruu_exe_name)); std::string path_base = get_absolute_cwd(); // we need to operate in the out folder since unruu only outputs to current if (change_dir(path_out)) return 2; int exit_code = 0; int res; res = run_program("unruu", path_ruu_exe_name, NULL); if (res != 0) { PRINT_ERROR("UnRUU failed"); exit_code = 4; } if (access("rom.zip", F_OK) == 0) { // PRINT_INFO("Found rom.zip"); } else if (access("rom_01.zip", F_OK) == 0 && access("rom_02.zip", F_OK) == 0) { PRINT_PROGRESS("Found rom_01.zip + rom_02.zip"); exit_code = 5; struct stat stat_file01; struct stat stat_file02; if (stat("rom_01.zip", &stat_file01) < 0) PRINT_ERROR("Couldn't get rom_01.zip filesize!"); else if (stat("rom_02.zip", &stat_file02) < 0) PRINT_ERROR("Couldn't get rom_02.zip filesize!"); else { const char *minor_rom; if (stat_file01.st_size > stat_file02.st_size) { PRINT_PROGRESS("rom_01.zip is the dominant zip and will be used for further processing"); rename("rom_01.zip", "rom.zip"); minor_rom = "rom_02.zip"; } else { PRINT_PROGRESS("rom_02.zip is the dominant zip and will be used for further processing"); rename("rom_02.zip", "rom.zip"); minor_rom = "rom_01.zip"; } if (access("android-info.txt", F_OK) < 0) { PRINT_PROGRESS("Attempting extract of android-info.txt from %s...", minor_rom); run_program("unzip", "-n", minor_rom, "android-info.txt", NULL); } PRINT_PROGRESS("Attempting extract of hboot/hosd from %s...", minor_rom); run_program("unzip", "-n", minor_rom, "hboot*", "hosd*", NULL); exit_code = 0; } } else { PRINT_ERROR("UnRUU failed to produce either rom.zip or rom_01.zip+rom_02.zip aborting!"); exit_code = 6; } change_dir(path_base); return exit_code; }