예제 #1
0
void av_metadata_dump(struct AVFormatContext *ic)
{
	unsigned int i;
	
	if (!ic)
		return;
	
	print_metadata(ic->metadata);
	
	for (i = 0; i < ic->nb_streams; i++)
		print_metadata(ic->streams[i]->metadata);
}
예제 #2
0
void
print_capture (const struct pcap_metadata *metadata, const char *pkt,
               unsigned int len, int verbose)
{
  struct timeval now;
  struct tm *loctime;
  char bufftime[BUFSIZ];

  gettimeofday (&now, NULL);
  loctime = gmtime (&(now.tv_sec));
  strftime (bufftime, BUFSIZ, "%H:%M:%S", loctime);

  if (verbose == JSON_OUTPUT) {
    printf ("{\"timestamp\": \"%s.%lu\", ", bufftime, now.tv_usec);
  } else {
    printf ("%s.%lu ", bufftime, now.tv_usec);
  }

  print_metadata (metadata, verbose);
  print_pkt (pkt, len, verbose);

  if (verbose == JSON_OUTPUT) {
    printf("}\n");
  }
}
예제 #3
0
PROCESS_THREAD(blinker_test_loop, ev, data)
{
  PROCESS_BEGIN();

  //	(1)	UART Output
  printf("OTA Image Example: Starting\n");
#if PLATFORM_HAS_LEDS
  //	(2)	Start blinking green LED
  leds_init();
  leds_on(BLINKER_PIN);
#else
  printf("Platform does not support LED. Unique ID: %u\n", OTA_EXAMPLE_UNIQUE_ID);
#endif

  ctimer_set( &blink_timer, (CLOCK_SECOND/2), blink_looper, NULL);

  //  (3) Get metadata about the current firmware version
  OTAMetadata_t current_firmware;
  get_current_metadata( &current_firmware );
  printf("\nCurrent Firmware\n");
  print_metadata( &current_firmware );

  ext_flash_init();

  int ota_slot;
  OTAMetadata_t ota_metadata;

  printf("\nNewest Firmware:\n");
  ota_slot = find_newest_ota_image();
  while( get_ota_slot_metadata( ota_slot, &ota_metadata ) );
  print_metadata( &ota_metadata );

  printf("\nOldest Firmware:\n");
  ota_slot = find_oldest_ota_image();
  while( get_ota_slot_metadata( ota_slot, &ota_metadata ) );
  print_metadata( &ota_metadata );

  int empty_slot = find_empty_ota_slot();
  printf("\nEmpty OTA slot: #%u\n", empty_slot);

  //  (4) OTA Download!
  process_start(ota_download_th_p, NULL);

  PROCESS_END();
}
예제 #4
0
void
print_function(FunctionSpec* function) 
{
    print_metadata(function);
    print_components(&function->components);
    print_input_mapping(&function->input_mapping);
    print_instructions(&function->instructions);
    print_output_instructions(&function->output_instructions);
}
예제 #5
0
void print_allmetadata( metadatalist_param_t *list)
{
  metadata_param_t *ptr;
  
  fprintf( logstream, "all metadata info: \n");
  ptr = list->first;
  while( ptr != NULL){
    print_metadata( ptr);
    ptr=ptr->next;
  }
}
예제 #6
0
/**
 * @brief Prints the metadata of all images of a database.
 *
 * @param db_file In memory structure representing a database.
 */
void do_list(const struct pictdb_file* db_file)
{
    // Print header
    print_header(&db_file->header);

    if (db_file->header.num_files == 0) {
        printf("<< empty database >>\n");
    } else {
        // Iterate over all elements in array of metadata and print them
        // only if they are valid
        for (uint32_t i = 0; i < db_file->header.max_files; ++i) {
            if (db_file->metadata[i].is_valid == NON_EMPTY) {
                print_metadata(&db_file->metadata[i]);
            }
        }
    }
}
예제 #7
0
파일: file.c 프로젝트: scality/dropletfs
static int
compare_digests(pentry_t *pe,
                dpl_dict_t *dict)
{
        char *remote = NULL;
        int ret;
        char *digest = NULL;

        if (FILE_LOCAL != pentry_get_placeholder(pe)) {
                LOG(LOG_DEBUG, "no local file");
                ret = -1;
                goto err;
        }

        digest = pentry_get_digest(pe);
        if (! digest) {
                LOG(LOG_NOTICE, "no digest");
                ret = -1;
                goto err;
        }

        print_metadata(dict);
        ret = -1;

        remote = dpl_dict_get_value(dict, "etag");
        if (remote) {
                LOG(LOG_DEBUG, "remote md5=%s", remote);
                LOG(LOG_DEBUG, "local md5=\"%.*s\"", MD5_DIGEST_LENGTH, digest);
                if (0 == memcmp(digest, remote, MD5_DIGEST_LENGTH)) {
                        ret = 0;
                } else {
                        pentry_set_digest(pe, remote);
                        LOG(LOG_DEBUG, "updated local md5=\"%.*s\"",
                            MD5_DIGEST_LENGTH, pentry_get_digest(pe));
                }
        }

  err:
        return ret;

}
예제 #8
0
int pdir(const char *dir, int skipdotfiles) {
	DIR *ectory;
	struct dirent *ent;
	struct stat file;
	char *fbuf, *dbuf;


	ectory = opendir(dir);
	dbuf = realpath(dir, NULL);

	while( (ent = readdir(ectory)) ) {
		if( (ent->d_name[0] == '.' && (!ent->d_name[1] || skipdotfiles)) ||
			(ent->d_name[1] == '.' && !ent->d_name[2]) )
			continue;

		asprintf(&fbuf, "%s/%s", dbuf, ent->d_name);

		stat(fbuf, &file);

		switch( file.st_mode & S_IFMT ) {
		case S_IFREG:
			print_metadata(fbuf, ent->d_name);
			break;

		case S_IFDIR:
			pdir(fbuf, skipdotfiles);
			break;
		}

		free(fbuf);
	}

	free(dbuf);
	closedir(ectory);

	return 0;
}
예제 #9
0
int main(int argc, char **argv)
{
	int fd, metadata_fd, ret;
	DIR *dir;
	int dir_fd;
	FILE *metadata_fp;

	ret = parse_args(argc, argv);
	if (ret) {
		fprintf(stderr, "Error: invalid argument.\n");
		usage(stderr);
		goto error;
	}

	if (s_help) {
		usage(stdout);
		exit(EXIT_SUCCESS);
	}

	ret = mkdir(s_outputname, S_IRWXU|S_IRWXG);
	if (ret) {
		perror("mkdir");
		goto error;
	}

	dir = opendir(s_outputname);
	if (!dir) {
		perror("opendir");
		goto error_rmdir;
	}
	dir_fd = dirfd(dir);
	if (dir_fd < 0) {
		perror("dirfd");
		goto error_closedir;
	}

	fd = openat(dir_fd, "datastream", O_RDWR|O_CREAT,
		    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	if (fd < 0) {
		perror("openat");
		goto error_closedirfd;
	}

	metadata_fd = openat(dir_fd, "metadata", O_RDWR|O_CREAT,
			     S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	if (metadata_fd < 0) {
		perror("openat");
		goto error_closedatastream;
	}
	metadata_fp = fdopen(metadata_fd, "w");
	if (!metadata_fp) {
		perror("fdopen");
		goto error_closemetadatafd;
	}

	babeltrace_uuid_generate(s_uuid);
	print_metadata(metadata_fp);
	trace_text(stdin, fd);

	ret = close(fd);
	if (ret)
		perror("close");
	exit(EXIT_SUCCESS);

	/* error handling */
error_closemetadatafd:
	ret = close(metadata_fd);
	if (ret)
		perror("close");
error_closedatastream:
	ret = close(fd);
	if (ret)
		perror("close");
error_closedirfd:
	ret = close(dir_fd);
	if (ret)
		perror("close");
error_closedir:
	ret = closedir(dir);
	if (ret)
		perror("closedir");
error_rmdir:
	ret = rmdir(s_outputname);
	if (ret)
		perror("rmdir");
error:
	exit(EXIT_FAILURE);
}
예제 #10
0
int main(int argc, char *argv[])
{
    if (!parseArgs(the_args, &argc, argv)
        || argc < 2 || show_help) {
        printUsage(argv[0], "DOCUMENT", the_args);
        exit(1);
    }

    if (show_text[0]) {
        if (!memcmp(show_text, "physical", 9)) {
            show_text_layout = poppler::page::physical_layout;
        } else if (!memcmp(show_text, "raw", 4)) {
            show_text_layout = poppler::page::raw_order_layout;
        } else {
            error(std::string("unrecognized text mode: '") + show_text + "'");
        }
    }

    std::string file_name(argv[1]);

    std::auto_ptr<poppler::document> doc(poppler::document::load_from_file(file_name));
    if (!doc.get()) {
        error("loading error");
    }
    if (doc->is_locked()) {
        error("encrypted document");
    }

    std::cout.setf(std::ios_base::boolalpha);

    if (show_all) {
        show_info = true;
        show_perm = true;
        show_metadata = true;
        show_toc = true;
        show_fonts = true;
        show_embedded_files = true;
        show_pages = true;
    }

    if (show_info) {
        print_info(doc.get());
    }
    if (show_perm) {
        print_perm(doc.get());
    }
    if (show_metadata) {
        print_metadata(doc.get());
    }
    if (show_toc) {
        std::auto_ptr<poppler::toc> doctoc(doc->create_toc());
        print_toc(doctoc.get());
    }
    if (show_fonts) {
        print_fonts(doc.get());
    }
    if (show_embedded_files) {
        print_embedded_files(doc.get());
    }
    if (show_pages) {
        const int pages = doc->pages();
        for (int i = 0; i < pages; ++i) {
            std::cout << "Page " << (i + 1) << "/" << pages << ":" << std::endl;
            std::auto_ptr<poppler::page> p(doc->create_page(i));
            print_page(p.get());
        }
    }
    if (show_text[0]) {
        const int pages = doc->pages();
        for (int i = 0; i < pages; ++i) {
            std::cout << "Page " << (i + 1) << "/" << pages << ":" << std::endl;
            std::auto_ptr<poppler::page> p(doc->create_page(i));
            print_page_text(p.get());
        }
    }

    return 0;
}
int main(int argc,char *argv[])
{
    fsl_player_s8 sCommand[128];
    fsl_player_s8 uri_buffer[500];
    fsl_player_thread_t display_thread;
    fsl_player_thread_t msg_thread;
    fsl_player_ret_val ret_val = FSL_PLAYER_SUCCESS;
    fsl_player_handle player_handle = NULL;
    fsl_player* pplayer = NULL;
    fsl_player_drm_format drm_format;
    fsl_player_config config;
    fsl_player_s32 ret;
    fsl_player_s32 volume = 1;

    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGABRT, signal_handler);
    signal(SIGILL,  signal_handler);
    signal(SIGFPE,  signal_handler);
    signal(SIGSEGV, signal_handler);

    if( argc < 2 ) {
        printf("Usage of command line player:\n");
        printf("    %s file_list\n", argv[0]);
        goto bail;
    }
        /* Initialisation */
    gst_init (&argc, &argv);

    // Default playbin.
    memset(&config, 0, sizeof(fsl_player_config));
    config.playbin_version = 2;
    config.api_version = GPLAYCORE_API_VERSION;
    config.features = (GPLAYCORE_FEATURE_AUTO_BUFFERING|GPLAYCORE_FEATURE_AUTO_REDIRECT_URI);
    config.timeout_second = GPLAYCORE_DEFAULT_TIMEOUT_SECOND;
    
    opt->info_interval_in_sec = 1;

    ret = parse_options(&config, opt, argc, argv);
    if( ret )
    {
        return -1;
    }

    fsl_player_element_property property[1];

    property[0].type = ELEMENT_TYPE_PLAYBIN;
    property[0].property_type = ELEMENT_PROPERTY_TYPE_INT;
    property[0].property_name = "flags";
    if (opt->enable_visual){
      property[0].value_int = 0x7f; /* default+native_video+buffering+visual */
    }else{
      property[0].value_int = 0x77; /* default+native_video+buffering */
    }
    property[0].next = NULL;
    config.ele_properties = property;

    if ((config.playbin_version==1)&&(config.video_sink_name==NULL)){
        config.video_sink_name = "autovideosink";
    }
    char *p;
    p = strrchr(opt->current->name, '.');
    PRINT("p=%s\n",p);	
    if(p&&!strncmp(p,".wav",4)){
	
        player_handle = fsl_player_initwav(&config,opt->current->name);
    }
    else 	
    player_handle = fsl_player_init(&config);
    if( NULL == player_handle )
    {
        PRINT("Failed: player_handle == NULL returned by fsl_player_init().\n");
        goto bail;
    }

    pplayer = (fsl_player*)player_handle;
    g_pplayer = pplayer;

    if (opt->info_interval_in_sec){
        FSL_PLAYER_CREATE_THREAD( &display_thread, display_thread_fun, player_handle );
    }
    FSL_PLAYER_CREATE_THREAD( &msg_thread, msg_thread_fun, player_handle );

    // Play the multimedia file directory after starting command line player.

    pplayer->klass->set_media_location(pplayer, opt->current->name, &drm_format);
    pplayer->klass->play(pplayer);

    // Print the help menu to let user know the operation.
    print_help(player_handle);

    kb_set_raw_term(STDIN_FILENO);

    while( FSL_PLAYER_FALSE == gbexit_main )
    {
        sCommand[0] = ' ';
        errno = 0;
        scanf("%s", sCommand);
        //read(STDIN_FILENO, sCommand, 1);
        if( EINTR == errno )
        {
            //printf("Timed out: EINTR == %d", errno);
        }
        switch( sCommand[0] )
        {
            case 'h': // display the operation Help.
                print_help(player_handle);
                break;

            case 'p': // Play.
             
                fsl_player_set_media_location(player_handle, filename2uri(uri_buffer,argv[1]), &drm_format);
                //pplayer->klass->set_media_location(pplayer, opt->current->name, &drm_format);
                pplayer->klass->play(pplayer);
                break;

            case 's': // Stop.
                pplayer->klass->stop(pplayer);
                break;

            case 'a': // pAuse when playing, play when paused.
                pplayer->klass->pause(pplayer);
                break;

            case 'e': // sEek.
            {
            #if 0
                fsl_player_u32 seek_point_sec = 0;
                fsl_player_u64 duration_ns = 0;
                fsl_player_u32 duration_sec = 0;
                pplayer->klass->get_property(pplayer, FSL_PLAYER_PROPERTY_DURATION, (void*)(&duration_ns));
                duration_sec = duration_ns / 1000000000;
                PRINT("Set seek point between [0,%u] seconds:", duration_sec);
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%s",sCommand);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                seek_point_sec = atoi(sCommand);
                if( seek_point_sec<0 || seek_point_sec>duration_sec  )
                {
                    printf("Invalid seek point!\n");
                    break;
                }
                pplayer->klass->seek(pplayer, seek_point_sec*1000);
                break;
            #else
                fsl_player_u32 seek_point_sec = 0;
                fsl_player_u64 duration_ns = 0;
                fsl_player_u32 duration_sec = 0;
                fsl_player_u32 seek_portion = 0;
                fsl_player_u32 seek_mode = 0;
                fsl_player_u32 flags = 0;
                pplayer->klass->get_property(pplayer, FSL_PLAYER_PROPERTY_DURATION, (void*)(&duration_ns));
                duration_sec = duration_ns / 1000000000;
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                PRINT("Select seek mode[Fast seek:0,Accurate seek:1]:");
                scanf("%s",sCommand);
                seek_mode = atoi(sCommand);
                if( seek_mode<0 || seek_mode>1  )
                {
                    printf("Invalid seek mode!\n");
                    break;
                }else{
                    if (seek_mode){
                        flags |= FSL_PLAYER_FLAG_SEEK_ACCURATE;
                    }
                }
                PRINT("%s seek to percentage[0:100] or second [t?]:", seek_mode?"Accurate":"Normal");
                scanf("%s",sCommand);
                if (sCommand[0]=='t'){
                    seek_point_sec = atoi(&sCommand[1]);
                }else{
                    seek_portion = atoi(sCommand);
                    
                    if( seek_portion<0 || seek_portion>100  )
                    {
                        printf("Invalid seek point!\n");
                        break;
                    }
                    seek_point_sec = (fsl_player_u32)(seek_portion * duration_sec / 100);
                }
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                
                pplayer->klass->seek(pplayer, seek_point_sec*1000, flags);
                break;
            #endif
            }

            case 'v': // Volume
            {
                double volume;
                PRINT("Set volume[0-1.0]:");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%lf",&volume);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                pplayer->klass->set_volume(pplayer, (volume));
                break;
            }

            case 'm': // Switch to mute or not
                pplayer->klass->mute(pplayer);
                break;

            case '>': // Play next file
                printf("next\n");
                if (playlist_next(pplayer, opt)==NULL){
                    player_exit(pplayer);
                }
                break;

            case '<': // Play previous file
                printf("previous\n");
                playlist_previous(pplayer, opt);
                break;

            case 'r': // Switch to repeated mode or not
            {
                fsl_player_s32 repeated_mode;
                PRINT("input repeated mode[0 for no repeated,1 for play list repeated,2 for current file repeated]:");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%d",&repeated_mode);
                if( repeated_mode<0 || repeated_mode>2  )
                {
                    printf("Invalid repeated mode!\n");
                }
                else
                {
                    opt->repeat = repeated_mode;
                }
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                //pplayer->klass->repeat(pplayer);
                break;
            }
#if 1
            case 'n': // Get the current video snapshot while playing
                //pplayer->klass->snapshot(pplayer);
                break;

            case 'o': // Set video output mode(LCD,NTSC,PAL,LCD&NTSC,LCD&PAL)
            {
                fsl_player_s32 mode = 0;
                PRINT("Set video output mode(LCD:0,NTSC:1,PAL:2,LCD&NTSC:3,LCD&PAL:4):");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%d",&mode);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                if( mode < 0 || mode >4 )
                {
                    printf("Invalid video output mode!\n");
                    break;
                }
                pplayer->klass->set_video_output(pplayer, mode);
                break;
            }

            case 'd': // Select the audio track
            {
                #if 1
                fsl_player_s32 audio_track_no = 0;
                fsl_player_s32 total_audio_no = 0;
                pplayer->klass->get_property(pplayer, FSL_PLAYER_PROPERTY_TOTAL_AUDIO_NO, (void*)(&total_audio_no));
                PRINT("input audio track number[0,%d]:",total_audio_no-1);
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%d",&audio_track_no);
                if( audio_track_no < 0 || audio_track_no > total_audio_no-1 )
                {
                    printf("Invalid audio track!\n");
                }
                else
                {
                    pplayer->klass->select_audio_track(pplayer, audio_track_no);
                }
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                #endif
                break;
            }

            case 'b': // Select the subtitle
            {
                #if 1
                fsl_player_s32 subtitle_no = 0;
                fsl_player_s32 total_subtitle_no = 0;
                pplayer->klass->get_property(pplayer, FSL_PLAYER_PROPERTY_TOTAL_SUBTITLE_NO, (void*)(&total_subtitle_no));
                PRINT("input subtitle number[0,%d]:",total_subtitle_no-1);
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%d",&subtitle_no);
                if( subtitle_no < 0 || subtitle_no > total_subtitle_no-1 )
                {
                    printf("Invalid audio track!\n");
                }
                else
                {
                    pplayer->klass->select_subtitle(pplayer, subtitle_no);
                }
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                #endif
                break;
            }
#endif
            case 'f': // Set full screen or not
                pplayer->klass->full_screen(pplayer);
                break;

            case 'y': // Set display screen mode
            {
                fsl_player_s32 display_screen_mode = 0;
                PRINT("Input screen mode[Normal:0,FullScreen:1,Zoom:2]:");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%d",&display_screen_mode);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                if( display_screen_mode < 0 || display_screen_mode > 2 )
                {
                    printf("Invalid display screen mode!\n");
                    break;
                }
                pplayer->klass->display_screen_mode(pplayer, display_screen_mode);
                break;
            }

            case 'z': // resize the width and height
            {
            #if 0
                fsl_player_display_parameter display_parameter;
                fsl_player_s32 width = 720;
                fsl_player_s32 height = 576;
                static fsl_player_s32 resize_index = 0;
                static float width_height_table[] = {0.25, 0.5, 0.75, 1, 2, 3, 4};
                static fsl_player_s32 offset_x_y_table[] = {600, 500, 400, 300, 200, 100, 0};
                if ((++resize_index)==6)
                    resize_index = 0;
                display_parameter.offsetx = 0;//offset_x_y_table[resize_index];
                display_parameter.offsety = 0;//offset_x_y_table[resize_index];
                display_parameter.disp_width = width_height_table[resize_index]*width;
                display_parameter.disp_height = width_height_table[resize_index]*height;
                pplayer->klass->resize(pplayer, display_parameter);
                break;
            #else
                fsl_player_display_parameter display_parameter;
                fsl_player_s8 sCommand_x[128];
                fsl_player_s8 sCommand_y[128];
                fsl_player_s8 sCommand_width[128];
                fsl_player_s8 sCommand_height[128];
                PRINT("Input [x,y,width,height]:");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%s %s %s %s",sCommand_x,sCommand_y,sCommand_width,sCommand_height);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                display_parameter.offsetx = atoi(sCommand_x);//offset_x_y_table[resize_index];
                display_parameter.offsety = atoi(sCommand_y);//offset_x_y_table[resize_index];
                display_parameter.disp_width = atoi(sCommand_width);
                display_parameter.disp_height = atoi(sCommand_height);
                if( display_parameter.offsetx < 0 || display_parameter.offsety < 0
                    || display_parameter.disp_width <= 0 || display_parameter.disp_height <= 0 )
                {
                    printf("Invalid resize parameters!\n");
                    break;
                }
                pplayer->klass->resize(pplayer, display_parameter);
                break;
            #endif
            }

            case 't': // Rotate 90 degree every time
            {
                fsl_player_rotation rotate_value;
                PRINT("Set rotation between 0, 90, 180, 270: ");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%s",sCommand);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                rotate_value = (fsl_player_rotation)atoi(sCommand);
                if( (fsl_player_s32)rotate_value != 0  && (fsl_player_s32)rotate_value != 90 &&  (fsl_player_s32)rotate_value != 180 
                &&   (fsl_player_s32)rotate_value != 270 )
                {
                    printf("Invalid rotation value=%d, rotation value should be between [0, 90, 180, 270]\n", rotate_value);
                    break;
                }
                pplayer->klass->rotate(player_handle, rotate_value);
                break;
            }

            case 'c': // playing direction and speed Control.
            {
                double playback_rate;
                PRINT("Set playing speed[-8,-4,-2,0.125,0.25,0.5,1,2,4,8]:");
                kb_restore_term(STDIN_FILENO);
                gbdisplay = FSL_PLAYER_FALSE;
                scanf("%lf",&playback_rate);
                gbdisplay = FSL_PLAYER_TRUE;
                kb_set_raw_term(STDIN_FILENO);
                pplayer->klass->set_playback_rate(pplayer, playback_rate);
                break;
            }

            case 'i': // Display Metadata Information
            {
                print_metadata(player_handle);
                break;
            }

            case 'x': // eXit
            {
                //pplayer->klass->stop(pplayer);
                //pplayer->klass->exit_message_loop(pplayer); // flush all messages left in the message queue.
                //pplayer->klass->send_message_exit(pplayer); // send a exit message.
                //gbexit_main = FSL_PLAYER_TRUE;
                pplayer->klass->send_message_exit(pplayer);
                player_exit(pplayer);
                break;
            }

            case '*': // Sleep 5 seconds
            {
                FSL_PLAYER_SLEEP(5000);
                break;
            }

            case '#': // Sleep 10 seconds
            {
                FSL_PLAYER_SLEEP(10000);
                break;
            }

            case 'P': //Property
            {
                char prop_name[64] = {0};
                PRINT("Please input property name:");
                scanf("%s",prop_name);
                prop_name[63] = '\0';
                if(FSL_PLAYER_SUCCESS != pplayer->klass->property(pplayer, prop_name)){
                    PRINT("Invalid property parameter\n");
                }
                
                break;
            }
            
            default:
                //printf("Default: Nothing has been done!\n");
                break;
        }
    }
    kb_restore_term (STDIN_FILENO);

    gbexit_display_thread = FSL_PLAYER_TRUE;
    if (opt->info_interval_in_sec){
        FSL_PLAYER_THREAD_JOIN(display_thread);
    }
    FSL_PLAYER_THREAD_JOIN(msg_thread);

    fsl_player_deinit(player_handle);

bail:
    destroyPlayList(opt->pl);

    return 0;
}
예제 #12
0
void local_player_task(uint_32 para) 
{
	_mqx_int return_code, res;
	my_audio_format_t format;
	FILE_PTR stream_ptr = NULL, stream_ptr1 = NULL;      //device_ptr = NULL, 
	uint_32 mclk_freq, fs_freq, bit_width = 0;
	I2S_STATISTICS_STRUCT stats;
	int32_t numberOfSamples =0, sampleProduced, bufOut;
	file_meta_data_t * metadata = NULL;
	audio_stream_type_t stream_type;
	char_ptr mem_ptr = NULL;
	boolean shell_cmd = FALSE;
        CCI_Ctx ctx;
	int32_t strLen, i;
	uint32_t file_extension=0;
	
	_task_id pcm_flush_id = MQX_NULL_TASK_ID;
	uint_32 cnt = 0;
	int32_t max_audio_buf_size = 0;
	lp_param_t *  lpp_param =  (lp_param_t *)para;
        TASK_TEMPLATE_STRUCT task_template;

	printf("local_player_task.. Enter 1\n");
	if (msi_snd_init_with_periodbuffer(1024, 18) != 0) /* for SPI sd card play FLAC, 18K buffer is at least! */
	{
		LOCALPLAY_LOG("  Error: Unable to open the device \"%s\".\n",
				AUDIO_DIVECE_NAME_STR);
		return;
	}
	
	/* create semaphore must before pcm_flush_task */
	if(MQX_OK != _lwsem_create(&pcm_decoded_sem, 0))
	{
		LOCALPLAY_LOG("\n Error - Unable to creat lwsem: pcm_decoded_sem\n");
	}
	
	
        LOCALPLAY_LOG("Creating pcm flush task.........\n");

        task_template.TASK_TEMPLATE_INDEX  = 0;
        task_template.TASK_ADDRESS         = pcm_flush_task;
        task_template.TASK_STACKSIZE       = 2000;
        task_template.TASK_PRIORITY        = 12;
        task_template.TASK_NAME            = "pcm_flush";
        task_template.TASK_ATTRIBUTES      = 0;
        task_template.CREATION_PARAMETER   = 0;
        task_template.DEFAULT_TIME_SLICE   = 0;

        pcm_flush_id = _task_create_blocked(0, 0, (uint_32)&task_template);

        if (pcm_flush_id  == MQX_NULL_TASK_ID)
        {
            printf("local_player_task create pcm_flush_task failed \n");
            goto clean_up;
        }
        else{
            gPcmFlushTaskFinish = 0;
            _task_ready(_task_get_td(pcm_flush_id));
            _lwevent_set(&player_event, PLAYER_EVENT_MSK_SONG_RESUME);
        }


	metadata = (file_meta_data_t *) _mem_alloc_system_zero(sizeof(file_meta_data_t));
	if (NULL == metadata) 
	{
		LOCALPLAY_LOG("\n Failed to allocate memory for metadata.\n");
		return;
	}

        decoding = TRUE;
	
	while (1) {

#ifndef  USB_ACCESSORY_PLAY		
		_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND, FALSE, 0);
#else
_lwevent_wait_ticks(
				&player_event,
				PLAYER_EVENT_MSK_SONG_READY | PLAYER_EVENT_MSK_SD_FS_UNMOUNTED
						| PLAYER_EVENT_MSK_SHELL_COMMAND | PLAYER_EVENT_MSK_USB_ATTACHED, FALSE, 0);		
#endif
		shell_cmd = FALSE;


#ifdef USB_ACCESSORY_PLAY
		if (player_event.VALUE & PLAYER_EVENT_MSK_USB_ATTACHED) {
					_lwevent_clear(&player_event, PLAYER_EVENT_MSK_USB_ATTACHED);
					//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_USB_ACC_ATTACHED \n");
					break;
				}
#endif

		if (player_event.VALUE & PLAYER_EVENT_MSK_SD_FS_UNMOUNTED) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SD_FS_UNMOUNTED);
			//LOCALPLAY_LOG("__guoyifang__: sd_player_task PLAYER_EVENT_MSK_SD_FS_UNMOUNTED \n");
			break;
		}	

		if (player_event.VALUE & PLAYER_EVENT_MSK_SONG_READY) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SONG_READY);
		}

		if (player_event.VALUE & PLAYER_EVENT_MSK_SHELL_COMMAND) {
			_lwevent_clear(&player_event, PLAYER_EVENT_MSK_SHELL_COMMAND);
			shell_cmd = TRUE;
		}

		LOCALPLAY_LOG(" --------------------------------------------------------------\n");

	    printf("play lock umount at %d\n",lpp_param->lp_type);
	    _lwsem_wait(lpp_param->mfs_io_sem);
	    /******************decoding is a critical value, assume decoding is TRUE every time.*******************/    
	    printf("SET decoding.\n");
	    decoding = TRUE; // next/prev btn ISR may clear decoding to 0
	    /*******************************************/
		/*config the audio subsystem according metadata*/
		        		printf(
		        				"  Open stream file %s\n", full_path);
		        		stream_ptr = fopen(full_path, "r");
		        		if (stream_ptr == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}

		        		stream_ptr1 = fopen(full_path, "r");
		        		if (stream_ptr1 == NULL) {
		        			printf("  Unable to open the file: %s\n", full_path);
		        			goto clean_up;
		        		}
		        		
		                /* Determine the extension of the file */ 
		                i=0;
		                strLen= strlen((const char *)full_path);

		                if(strLen > 4){
		                    /* find the '.' */
		                    while(strLen--){
		                        if(full_path[i]=='.')
		                            break;
		                        i++;
		                    }
		                    if(strLen){
		                        char *p;
		                        /* Copy out the extension : 8.3 filename */
		                        memcpy(&file_extension, full_path+i+1, 3);
		                        p = (char *) (&file_extension);
		                        for(i = 0; i < 4; i++, p++){
		                            if((*p >= 'a') && (*p <= 'z')){
		                                *p -= ('a' - 'A');
		                            }
		                        }
		                    } 

		                    ctx.user_data = (void*) stream_ptr;
		                    ctx.cci_dec_read = get_file_data;;
		                    ctx.cci_dec_seek = seek_file_data;
		                    ctx.cci_dec_tell = get_file_position;

		                    /* Check if metadata was found. */
		                    return_code = cci_extract_meta_data(file_extension, metadata, &ctx);        
		        		    if (return_code != 0) {
		        			    printf("\n Metadata not found\n");
		        			    goto clean_up;
		        		    }

		        		    print_metadata(metadata); //todo

		                } else {
		        			printf("\n Metadata not found\n");
		        			goto clean_up;
		                }
		                if ( metadata->stream_type == STREAM_TYPE_MP3 ) {
		                	/* Seek from the beginning of the file */ 
		                    seek_file_data(0, metadata->start_pos, 0, stream_ptr);
		                } else {
		                	/* Seek from the beginning of the file */
		                	seek_file_data(0, 0, 0, stream_ptr);
		        		}
		        
		        
		        stream_type = metadata->stream_type;

#if 0	
		format.audio_format.ENDIAN = AUDIO_LITTLE_ENDIAN;
		format.audio_format.ALIGNMENT = AUDIO_ALIGNMENT_LEFT;
		if((streamType == kCodecStreamTypePcm) ||	// bitsPerSample Value is 8/16/24
				/*
				 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
				 */
				(streamType == kCodecStreamTypeImaAdpcm) || // bitsPerSample Value is 4
				(streamType == kCodecStreamTypeMsAdpcm))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->i32BitsPerSample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
		
		format.audio_format.SIZE = (format.audio_format.BITS + 7)/8;

		
		format.audio_format.CHANNELS = metadata->i32NumChannels;
		format.fs_freq = metadata->u32SampleRate;

		fs_freq = format.fs_freq;
		mclk_freq = fs_freq * CLK_MULT;
		// Setup audio data format in device 
		if (ioctl(device_ptr, IO_IOCTL_AUDIO_SET_IO_DATA_FORMAT,
				&format.audio_format) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Input data format not supported.\n");
			goto clean_up;
		}
		// Setup rest of parameters - master clock, valid data bits and sampling frequency 
		if ((ioctl(device_ptr, IO_IOCTL_I2S_SET_MCLK_FREQ, &mclk_freq) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_DATA_BITS,
						&format.audio_format.BITS) != I2S_OK)
				|| (ioctl(device_ptr, IO_IOCTL_I2S_SET_FS_FREQ, &fs_freq)
						!= I2S_OK)) {
			LOCALPLAY_LOG("  Error: Unable to setup \"%s\" device driver.\n",
					AUDIO_DIVECE_NAME_STR);
			goto clean_up;
		}

		// Setup audio codec 
		return_code = SetupCodec(device_ptr);
		if (return_code != 0) {
			LOCALPLAY_LOG("  Audio codec configuration failed. Error 0x%X.\n",
					return_code);
			goto clean_up;
		}

		ioctl(device_ptr, IO_IOCTL_I2S_GET_FS_FREQ, &fs_freq);
		ioctl(device_ptr, IO_IOCTL_I2S_GET_DATA_BITS, &bit_width);
		LOCALPLAY_LOG("  Playback information\n");
		LOCALPLAY_LOG("  Sampling frequency:     %d Hz\n", fs_freq);
		LOCALPLAY_LOG("  Bit depth:              %d bits\n", (uint_8)bit_width);
		LOCALPLAY_LOG("  Channels:               ");
		
		if (format.audio_format.CHANNELS == 1) {
			LOCALPLAY_LOG("mono\n");
		} else {
			LOCALPLAY_LOG("stereo\n");
		}
#else
		if((stream_type == STREAM_TYPE_PCM) ||	// bitsPerSample Value is 8/16/24
		/*
		 * The demo not support kCodecStreamTypeImaAdpcm/kCodecStreamTypeMsAdpcm currently.
		 */
		(stream_type == STREAM_TYPE_IMAADPCM) || // bitsPerSample Value is 4
		(stream_type == STREAM_TYPE_MSADPCM))	// bitsPerSample Value is 4
		{	
			format.audio_format.BITS = metadata->bits_per_sample;
		}else{
			format.audio_format.BITS = 16; 
		}
		
		format.audio_format.CHANNELS = metadata->num_channels;
		// Currently, the wave decoder output 16bits only for kCodecStreamTypePcm.
		format.audio_format.BITS = 16;
#if 0
		if(audio_ioctl(setChNum, format.audio_format.CHANNELS)!= I2S_OK)
        {
		  LOCALPLAY_LOG("  Error: audio_ioctl setChNum failed.\n");
		  goto clean_up;
        }
		if(audio_ioctl(setBitWidth, format.audio_format.BITS)!= I2S_OK)
		{

		  LOCALPLAY_LOG("  Error: audio_ioctl setBitWidth failed.\n");
		  goto clean_up;
		}
#endif
		
		format.fs_freq = metadata->sample_rate;
		
#if 0
		if(audio_ioctl(setSamplerate, format.fs_freq)!= I2S_OK)
	    {
		  LOCALPLAY_LOG("  Error: audio_ioctl setSamplerate failed.\n");
		  goto clean_up;
	    }
#endif
		msi_snd_set_format(format.fs_freq, format.audio_format.BITS, format.audio_format.CHANNELS);
	

#endif

		mem_ptr = (char_ptr) _mem_alloc_system_zero(codec_get_mem_info(stream_type));
		if (NULL == mem_ptr) {
			LOCALPLAY_LOG("Failed to allocate memory for the decoder.\n");
			goto clean_up;
		}

		// MP4 decoder need two fd
		g_userData[0] = (int) stream_ptr;
		g_userData[1] = (int) stream_ptr1;
		if (metadata->audio_sub_type == MEDIA_SUBTYPE_ADTS)
			g_userData[2] = 1;
		else if (metadata->audio_sub_type == MEDIA_SUBTYPE_M4A)
			g_userData[2] = 2;
		else if ( metadata->stream_type == STREAM_TYPE_OPUS )
		{
			g_userData[2] = metadata->sample_rate;
			g_userData[3] = metadata->num_channels;
	    }
		else
			g_userData[2] = 0; 

		g_callbackFunctionArray[0] = (int32_t *) &get_file_data;
		g_callbackFunctionArray[1] = (int32_t *) &seek_file_data;
		g_callbackFunctionArray[2] = (int32_t *) &get_file_position;

		while (1) {
			res = codec_init(stream_type, (long **)&mem_ptr,g_callbackFunctionArray,
								&g_userData[0]);
			if (res == CODEC_INIT_ERROR) {
				LOCALPLAY_LOG("\n  Codec Init Failed with error code %d\n", res);
				decoding = FALSE; 
				goto clean_up;
			}
			if (res == CODEC_MORE_DATA_REQUIRED) {
				LOCALPLAY_LOG("\n  More Data Processing Required for Init \n");
			}
			if (res == CODEC_SUCCESS) {
				LOCALPLAY_LOG("\n  Codec Init Done Successfully \n\n");
				break;
			}
			else {
				printf("codec init other err\n");
				decoding = FALSE;
				goto clean_up;
			}
		}

		if (res == CODEC_SUCCESS) {
			LOCALPLAY_LOG("  Playing %s...\n\n", full_path);
		//	ioctl(device_ptr, IO_IOCTL_I2S_CLEAR_STATISTICS, NULL);
			/* Reset variables before every song's playbacking */
			
			//printf("SET decoding.\n");
			//decoding = TRUE; // next/prev btn ISR may clear decoding to 0
			cnt = 0;

			max_audio_buf_size = 0;
			g_audio_buf_ptr = NULL;
			//_lwevent_clear(&player_event, PLAYER_EVENT_MSK_AUDIO_BUF_FILLED);
			/* Clear pcm_decoded_sem for play next song */
			_lwsem_poll(&pcm_decoded_sem);
			_lwsem_poll(&pcm_decoded_sem);  
					
			if(MQX_OK != _lwsem_create(&pcm_flush_sem, AUDIO_BUF_CNT))
			{
				LOCALPLAY_LOG("\n Error - Unable to create lwsem: pcm_flush_sem\n");
			}
			
			/*
			 * umute
			 */
			msi_snd_umute();
			//sai_dma_output_init();
			
			while (decoding) {
				/*
				 * For FLAC decoder, it produced more than 18K bytes per frame, and takes about 30ms. 
				 * While take 44.1K/16bit/2ch/4Kbytes DMA buffer as example, the margin time is 4K/4/2/44100~=10ms. 
				 * We need bigger DMA buffer, or decode in a ping-pong way.
				 */		
				res = codec_decode(stream_type, (long **)&mem_ptr, &sampleProduced,
										&bufOut);
              
				if (res == CODEC_END_OF_DECODE) {					
					printf("\n  End of Decode \n");
					break;
				}
				else if (res == CODEC_DECODE_ERROR) {
					printf("\n  Codec Decode Failed \n");
					break;
				}
				else if(res != CODEC_SUCCESS){
					printf("codec_decode else err %d\n",res);
						break;
				}
				
				cnt += sampleProduced;
				
				while (decoding) 
				 {
					numberOfSamples = codec_get_pcm_samples(stream_type,
											(long **)&mem_ptr, &sampleProduced, &bufOut);
					if (numberOfSamples == 0)
						break;
					
#if 1
					if (max_audio_buf_size < sampleProduced) { //More bigger buffer needed
						max_audio_buf_size = sampleProduced;
						if (NULL != g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Bigger buffer needed.\n");
							_mem_free(g_audio_buf_ptr);
						}
						g_audio_buf_ptr = (uchar_ptr) _mem_alloc_system_zero(max_audio_buf_size);
						if (NULL == g_audio_buf_ptr) {
							LOCALPLAY_LOG(" Failed to allocate g_audio_buf_ptr. max_audio_buf_size %d \n", max_audio_buf_size);
							decoding = 0;
							break;
						}	
#if 1
						//sai_dma_buffer_adjust(sampleProduced);			
#endif
					}
#endif
					
				    if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
				    {
					  LOCALPLAY_LOG("\n Error: Wait for pcm_flush_sem failed.\n");
					 // _task_set_error(res);
				    }
				    
					_mem_copy((void *)bufOut, g_audio_buf_ptr, sampleProduced);
                                        //g_audio_buf_ptr = bufOut;
					g_buf_bytes_to_flush = sampleProduced;
		
					if (_lwsem_post(&pcm_decoded_sem) != MQX_OK)
					 {
					   LOCALPLAY_LOG("\n  pcm_flush : Error - Unable to set pcm_decoded_sem.");
					 }

					if (numberOfSamples == sampleProduced)
						sampleProduced = 0;
				 }//end while decoding
	 	  }//end while decoding
		}//end if res==kCodeSuccess
		
		#if 0
		fflush(device_ptr);
		#else
		msi_snd_mute();

                if (MQX_OK != _lwsem_wait(&pcm_flush_sem))
                    LOCALPLAY_LOG("\n Error: Wait for latest pcm_flush_sem failed.\n");
		msi_snd_flush();
		#endif
		
#if 1
		//sai_dma_output_stop();
#endif	
#if 0
		/* Print transfer statistics */
		if (ioctl(device_ptr, IO_IOCTL_I2S_GET_STATISTICS, &stats) != I2S_OK) {
			LOCALPLAY_LOG("  Error: Cannot read I2S statistics.\n");
		} else {
			LOCALPLAY_LOG("\n  Playback stats\n");
			LOCALPLAY_LOG("  Total interrupts:              %d\n", stats.INTERRUPTS);
			LOCALPLAY_LOG("  Bytes requested for transmit:  %d\n",
					stats.PACKETS_REQUESTED * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Bytes transmitted:             %d\n",
					stats.TX_PACKETS * format.audio_format.SIZE);
			LOCALPLAY_LOG("  Underruns of hardware FIFO:    %d\n", stats.FIFO_ERROR);
			LOCALPLAY_LOG("  Software buffer empty:         %d\n", stats.BUFFER_ERROR);
		}
#endif
	        LOCALPLAY_LOG("\n  DONE\n");
			
		clean_up:
		printf("done to clean up,decoding %d \n",decoding);		
		/* Clean up for next song */
		if (NULL != mem_ptr) {
			_mem_free(mem_ptr);
			mem_ptr = NULL;
		}
		if (NULL != g_audio_buf_ptr) {
			_mem_free(g_audio_buf_ptr);
			g_audio_buf_ptr = NULL;
		}
		if (NULL != stream_ptr) {
			res = fclose(stream_ptr);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr = NULL;
		}
		if (NULL != stream_ptr1) {
			res = fclose(stream_ptr1);
			if ((res != MQX_OK)&&(res != MFS_DISK_IS_WRITE_PROTECTED)) {
				/*LOCALPLAY_LOG*/printf("  Error: Unable to close file 0x%x.\n", res);
			}
			stream_ptr1 = NULL;
		}
		
		if(MQX_OK != _lwsem_destroy(&pcm_flush_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_flush_sem\n");
		  }

		if (decoding == TRUE) { // playback finished in normal way, ie, next/prev not pressed
			if (!shell_cmd) { 	// and was not triggered by Shell
				// just like next btn being pressed
				_lwevent_set(&player_event, PLAYER_EVENT_MSK_NEXT_BTN_PRESSED);
			}
		}
		
	    /* if exit this task ,must route this point ! */
	    printf("play unlock umount at %d\n",lpp_param->lp_type);
	    _lwsem_post(lpp_param->mfs_io_sem);
	}//end while(1)
#if 0
	// clean up further
	if (NULL != device_ptr) {	
		if (fclose(device_ptr) != MQX_OK) {
			LOCALPLAY_LOG("  Error: Unable to close \"%s\" device driver.\n",
					full_path);
		}
	}
#else	
	msi_snd_deinit();
#endif
			
	if (NULL != metadata)
		_mem_free(metadata);	

	if (MQX_NULL_TASK_ID != pcm_flush_id)
	  {
            gPcmFlushTaskFinish = 1;
	    _lwsem_post(&pcm_decoded_sem);
            while(gPcmFlushTaskFinish == 1){
                _sched_yield();
            }

            //_task_destroy(pcm_flush_id);
	    pcm_flush_id = MQX_NULL_TASK_ID;
	    ///*LOCALPLAY_LOG*/printf(" pcm flush task destoryed \n");
	  }
	
	if(MQX_OK != _lwsem_destroy(&pcm_decoded_sem))
		  {
			LOCALPLAY_LOG("\n Error - Unable to destroy lwsem: pcm_decoded_sem\n");
		  }
	
  //printf("__guoyifang__: sd_player_task %d set PLAYER_TASK_KILLED.\n",lpp_param->lp_type);
  _lwevent_set(&player_event, PLAYER_EVENT_MSK_PLAYER_TASK_KILLED);
  
  printf("sd_player_task  exit.\n");
  //_task_block(); //wait for being destroyed
  
}
예제 #13
0
int main(int argc, char *argv[])
{
	struct cmdline_options	opts = {
		.cache_file	=  CACHE_FILE,
		.base_oid	=  BASE_OID,
		.conf_file	=  CONF_FILE,
		.cache_prog	=  CACHE_REGEN_PROG,
	};

	bool				is_ok;
	int				cache_fd;
	struct cache_entry		*cache_entries;
	size_t				num_cache_entries;
	int				rc;
	unsigned int			attr_idx = SNMPD_IDX_UNKNOWN;
	size_t				req_cache_idx;
	struct oid_info const		*sub_oid;
	size_t				base_oid_len;

	while (1) {
		int		c = getopt_long(argc, argv, "gns", CMDLINE_OPTIONS, 0);
		if (c==-1) break;

		switch (c) {
		case CMD_HELP:		show_help();
		case CMD_VERSION:	show_version();
		case CMD_BASE_OID:	opts.base_oid = optarg; break;
		case CMD_CACHE:		opts.cache_file = optarg; break;
		case CMD_CACHE_PROGRAM:	opts.cache_prog = optarg; break;
		case CMD_CONF:		opts.conf_file = optarg; break;
		case 'g':		opts.op_get = 1; break;
		case 's':		opts.op_set = 1; break;
		case 'n':		opts.op_get_next = 1; break;
		default:
			fputs("Try '--help' for more information.\n", stderr);
			exit(EX_USAGE);
		}
	}

	is_ok = false;
	base_oid_len = strlen(opts.base_oid);

	if (opts.op_get + opts.op_set + opts.op_get_next > 1)
		fputs("more than one operation specified\n", stderr);
	else if (opts.op_get + opts.op_set + opts.op_get_next == 0)
		fputs("no operation specified\n", stderr);
	else if (optind + 1 != argc)
		fputs("no/too much OID specified\n", stderr);
	else if (strncmp(opts.base_oid, argv[optind], base_oid_len) &&
		 argv[optind][base_oid_len] != '\0' &&
		 argv[optind][base_oid_len] != '.')
		fputs("unsupported OID\n", stderr);
	else if (!parse_oid(&argv[optind][base_oid_len], &sub_oid, &attr_idx))
		;			/* noop */
	else if ((opts.op_get || opts.op_set) &&
		 (sub_oid == NULL || attr_idx == SNMPD_IDX_UNKNOWN ||
		  (sub_oid->num_suboid && attr_idx >= sub_oid->num_suboid))) {
		fprintf(stderr, "sub_oid=%p, idx=%u\n", sub_oid, attr_idx);
		fputs("unknown OID\n", stderr);
		return EX_UNAVAILABLE;
	} else
		is_ok = true;

	if (!is_ok)
		exit(EX_USAGE);

	if (opts.op_set) {
		puts("not-writable");
		return EXIT_SUCCESS;
	}

	if (opts.op_get_next && sub_oid == NULL) {
		sub_oid = &SUB_OIDS[0];
		assert(attr_idx == SNMPD_IDX_UNKNOWN);
	}

	assert(sub_oid != NULL);

	cache_fd = open_cache_file(opts.conf_file, opts.cache_file, opts.cache_prog);
	if (cache_fd < 0)
		exit(-cache_fd);

	rc = read_cache_file(cache_fd, &cache_entries, &num_cache_entries);
	if (rc < 0)
		exit(-rc);

	close(cache_fd);

	if (sub_oid->num_suboid == 0) {
		size_t				i;

		if (attr_idx == SNMPD_IDX_UNKNOWN && opts.op_get_next)
			req_cache_idx = 0;
		else
			req_cache_idx = num_cache_entries;

		for (i = 0; i < num_cache_entries; ++i) {
			if (cache_entries[i].idx != attr_idx)
				continue;

			req_cache_idx = i;
			if (opts.op_get_next) {
				++req_cache_idx;

				if (req_cache_idx >= num_cache_entries) {
					req_cache_idx = 0;
					++sub_oid;
				}
			}

			break;
		}
	} else if (opts.op_get_next) {
		if (attr_idx == SNMPD_IDX_UNKNOWN)
			req_cache_idx = 0;
		else if (attr_idx + 1 != sub_oid->num_suboid)
			req_cache_idx = attr_idx;
		else {
			req_cache_idx = 0;
			++sub_oid;
		}
	} else
		req_cache_idx = attr_idx;

	assert(sub_oid->num_suboid == 0 || req_cache_idx < sub_oid->num_suboid);

	if (sub_oid->idx == SNMPD_OID_METADATA) {
		print_metadata(opts.base_oid, sub_oid, req_cache_idx,
			       num_cache_entries);
	} else if (req_cache_idx < num_cache_entries && sub_oid->oid != 0) {
		rc = read_sysfs_cache(&cache_entries[req_cache_idx]);
		if (rc < 0)
			exit(-rc);

		print_cache(&cache_entries[req_cache_idx],
			    opts.base_oid, sub_oid);
	}


	free(cache_entries);
}