Пример #1
0
int file_is_webm(struct WebmInputContext *webm_ctx,
                 struct VpxInputContext *vpx_ctx) {
  uint32_t i, n;
  int track_type = -1;
  int codec_id;

  nestegg_io io = {nestegg_read_cb, nestegg_seek_cb, nestegg_tell_cb, 0};
  nestegg_video_params params;

  io.userdata = vpx_ctx->file;
  if (nestegg_init(&webm_ctx->nestegg_ctx, io, NULL))
    goto fail;

  if (nestegg_track_count(webm_ctx->nestegg_ctx, &n))
    goto fail;

  for (i = 0; i < n; i++) {
    track_type = nestegg_track_type(webm_ctx->nestegg_ctx, i);

    if (track_type == NESTEGG_TRACK_VIDEO)
      break;
    else if (track_type < 0)
      goto fail;
  }

  codec_id = nestegg_track_codec_id(webm_ctx->nestegg_ctx, i);
  if (codec_id == NESTEGG_CODEC_VP8) {
    vpx_ctx->fourcc = VP8_FOURCC_MASK;
  } else if (codec_id == NESTEGG_CODEC_VP9) {
    vpx_ctx->fourcc = VP9_FOURCC_MASK;
  } else {
    fatal("Not VPx video, quitting.\n");
  }

  webm_ctx->video_track = i;

  if (nestegg_track_video_params(webm_ctx->nestegg_ctx, i, &params))
    goto fail;

  vpx_ctx->framerate.denominator = 0;
  vpx_ctx->framerate.numerator = 0;
  vpx_ctx->width = params.width;
  vpx_ctx->height = params.height;

  return 1;

 fail:
  webm_ctx->nestegg_ctx = NULL;
  rewind(vpx_ctx->file);

  return 0;
}
Пример #2
0
int
main(int argc, char * argv[])
{
  FILE * fp;
  int r, type;
  nestegg * ctx;
  nestegg_audio_params aparams;
  nestegg_packet * pkt;
  nestegg_video_params vparams;
  size_t length, size;
  uint64_t duration, tstamp, pkt_tstamp;
  unsigned char * codec_data, * ptr;
  unsigned int cnt, i, j, track, tracks, pkt_cnt, pkt_track;
  unsigned int data_items = 0;
  nestegg_io io = {
    stdio_read,
    stdio_seek,
    stdio_tell,
    NULL
  };

  if (argc != 2)
    return EXIT_FAILURE;

  fp = fopen(argv[1], "rb");
  if (!fp)
    return EXIT_FAILURE;

  io.userdata = fp;

  ctx = NULL;
  r = nestegg_init(&ctx, io, log_callback, -1);
  if (r != 0)
    return EXIT_FAILURE;

  nestegg_track_count(ctx, &tracks);
  r = nestegg_duration(ctx, &duration);
  if (r == 0) {
#if defined(DEBUG)
    fprintf(stderr, "media has %u tracks and duration %fs\n", tracks, duration / 1e9);
#endif
  } else {
#if defined(DEBUG)
    fprintf(stderr, "media has %u tracks and unknown duration, using 10s default\n", tracks);
#endif
    duration = 10000000000;
  }

  for (i = 0; i < tracks; ++i) {
    type = nestegg_track_type(ctx, i);
#if defined(DEBUG)
    fprintf(stderr, "track %u: type: %d codec: %d", i,
            type, nestegg_track_codec_id(ctx, i));
#endif
    nestegg_track_codec_data_count(ctx, i, &data_items);
    for (j = 0; j < data_items; ++j) {
      nestegg_track_codec_data(ctx, i, j, &codec_data, &length);
#if defined(DEBUG)
      fprintf(stderr, " (%p, %u)", codec_data, (unsigned int) length);
#endif
    }
    if (type == NESTEGG_TRACK_VIDEO) {
      nestegg_track_video_params(ctx, i, &vparams);
#if defined(DEBUG)
      fprintf(stderr, " video: %ux%u (d: %ux%u %ux%ux%ux%u)",
              vparams.width, vparams.height,
              vparams.display_width, vparams.display_height,
              vparams.crop_top, vparams.crop_left, vparams.crop_bottom, vparams.crop_right);
#endif
    } else if (type == NESTEGG_TRACK_AUDIO) {
      nestegg_track_audio_params(ctx, i, &aparams);
#if defined(DEBUG)
      fprintf(stderr, " audio: %.2fhz %u bit %u channels",
              aparams.rate, aparams.depth, aparams.channels);
#endif
    }
#if defined(DEBUG)
    fprintf(stderr, "\n");
#endif
  }

#if defined(SEEK_TEST)
#if defined(DEBUG)
  fprintf(stderr, "seek to middle\n");
#endif
  r = nestegg_track_seek(ctx, 0, duration / 2);
  if (r == 0) {
#if defined(DEBUG)
    fprintf(stderr, "middle ");
#endif
    r = nestegg_read_packet(ctx, &pkt);
    if (r == 1) {
      nestegg_packet_track(pkt, &track);
      nestegg_packet_count(pkt, &cnt);
      nestegg_packet_tstamp(pkt, &tstamp);
#if defined(DEBUG)
      fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt);
#endif
      nestegg_free_packet(pkt);
    } else {
#if defined(DEBUG)
      fprintf(stderr, "middle seek failed\n");
#endif
    }
  }

#if defined(DEBUG)
  fprintf(stderr, "seek to ~end\n");
#endif
  r = nestegg_track_seek(ctx, 0, duration - (duration / 10));
  if (r == 0) {
#if defined(DEBUG)
    fprintf(stderr, "end ");
#endif
    r = nestegg_read_packet(ctx, &pkt);
    if (r == 1) {
      nestegg_packet_track(pkt, &track);
      nestegg_packet_count(pkt, &cnt);
      nestegg_packet_tstamp(pkt, &tstamp);
#if defined(DEBUG)
      fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt);
#endif
      nestegg_free_packet(pkt);
    } else {
#if defined(DEBUG)
      fprintf(stderr, "end seek failed\n");
#endif
    }
  }

#if defined(DEBUG)
  fprintf(stderr, "seek to ~start\n");
#endif
  r = nestegg_track_seek(ctx, 0, duration / 10);
  if (r == 0) {
#if defined(DEBUG)
    fprintf(stderr, "start ");
#endif
    r = nestegg_read_packet(ctx, &pkt);
    if (r == 1) {
      nestegg_packet_track(pkt, &track);
      nestegg_packet_count(pkt, &cnt);
      nestegg_packet_tstamp(pkt, &tstamp);
#if defined(DEBUG)
      fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt);
#endif
      nestegg_free_packet(pkt);
    } else {
#if defined(DEBUG)
      fprintf(stderr, "start seek failed\n");
#endif
    }
  }
#endif

  while (nestegg_read_packet(ctx, &pkt) > 0) {
    nestegg_packet_track(pkt, &pkt_track);
    nestegg_packet_count(pkt, &pkt_cnt);
    nestegg_packet_tstamp(pkt, &pkt_tstamp);

#if defined(DEBUG)
    fprintf(stderr, "t %u pts %f frames %u: ", pkt_track, pkt_tstamp / 1e9, pkt_cnt);
#endif

    for (i = 0; i < pkt_cnt; ++i) {
      nestegg_packet_data(pkt, i, &ptr, &size);
#if defined(DEBUG)
      fprintf(stderr, "%u ", (unsigned int) size);
#endif
    }
#if defined(DEBUG)
    fprintf(stderr, "\n");
#endif

    nestegg_free_packet(pkt);
  }

  nestegg_destroy(ctx);
  fclose(fp);

  return EXIT_SUCCESS;
}
Пример #3
0
webm_context *webm_start_playback(const char *path, int volume)
{
    webm_context *ctx;
    nestegg_io io;
    int video_track = -1, audio_track = -1;

    quit_video = 0;
    ctx = malloc(sizeof(*ctx));
    if(!ctx) return NULL;
    memset(ctx, 0, sizeof(*ctx));

    // set up I/O callbacks
    io.read = webm_read;
    io.seek = webm_seek;
    io.tell = webm_tell;

    // open video file
    ctx->packhandle = openpackfile(path, packfile);
    if(ctx->packhandle < 0)
    {
        printf("Error: Unable to open file %s for playback\n", path);
        goto error1;
    }
    io.userdata = (void*)ctx->packhandle;
    if(nestegg_init(&(ctx->nestegg_ctx), io, NULL, -1) < 0) goto error2;

    // get number of tracks
    unsigned int num_tracks, i;
    if(nestegg_track_count(ctx->nestegg_ctx, &num_tracks) < 0) goto error3;

    // find the first video and audio tracks
    for (i = 0; i < num_tracks; i++)
    {
        int track_type = nestegg_track_type(ctx->nestegg_ctx, i);
        int codec = nestegg_track_codec_id(ctx->nestegg_ctx, i);
        if (track_type == NESTEGG_TRACK_VIDEO)
        {
            if(codec != NESTEGG_CODEC_VP8)
            {
                printf("Error: unsupported video codec; only VP8 is supported\n");
                goto error3;
            }
            video_track = i;
        }
        else if (track_type == NESTEGG_TRACK_AUDIO)
        {
            if(codec != NESTEGG_CODEC_VORBIS)
            {
                printf("Error: unsupported audio codec; only Vorbis is supported\n");
                goto error3;
            }
            audio_track = i;
        }
    }

    // set up video
    ctx->video_track = video_track;
    init_video(ctx->nestegg_ctx, ctx->video_track, &(ctx->video_ctx));
    ctx->the_video_thread = thread_create(video_thread, "video", &(ctx->video_ctx));
    assert(ctx->the_video_thread);

    // set up audio, if applicable
    ctx->audio_track = audio_track;
    if (audio_track >= 0)
    {
        // use the audio track of this file
        init_audio(ctx->nestegg_ctx, ctx->audio_track, &(ctx->audio_ctx), volume);
        ctx->the_audio_thread = thread_create(audio_thread, "audio", &(ctx->audio_ctx));
        assert(ctx->the_audio_thread);
    }
    else if (sound_query_music(NULL, NULL))
    {
        // continue to play the BGM that's already playing
        ctx->the_audio_thread = thread_create(bgm_update_thread, "bgm", NULL);
        assert(ctx->the_audio_thread);
    }

    // finally, start the demuxing thread
    ctx->the_demux_thread = thread_create(demux_thread, "demux", ctx);
    assert(ctx->the_demux_thread);
    return ctx;

error3:
    nestegg_destroy(ctx->nestegg_ctx);
error2:
    closepackfile(ctx->packhandle);
error1:
    free(ctx);
    return NULL;
}