game-stop / veejay

Veejay is a visual instrument and realtime video sampler (for live video improvisation)
http://veejayhq.net
84 stars 12 forks source link

add hwaccel for codecs that support it #174

Open game-stop opened 6 years ago

game-stop commented 6 years ago

MJPEG hwaccel is supported by ffmpeg using libvaapi backend (both amd and intel, choose the correct driver)

1) Setup va driver 2) Test using ffmpeg -hwaccel vdpau test.avi 3) Implement:

Refer to ffmpeg.c and implement:

game-stop commented 1 year ago
  // Initialize libavcodec and libavformat.
  avcodec_register_all();
  avformat_network_init();

  // Open the MJPEG file.
  AVFormatContext *format_context = avformat_alloc_context();
  if (avformat_open_input(&format_context, argv[1], NULL, NULL) < 0) {
    fprintf(stderr, "Could not open MJPEG file\n");
    return 1;
  }

  // Get the video stream.
  AVStream *video_stream = format_context->streams[0];

  // Find the decoder for the video stream.
  AVCodec *decoder = avcodec_find_decoder(video_stream->codecpar->codec_id);
  if (!decoder) {
    fprintf(stderr, "Could not find decoder for video stream\n");
    return 1;
  }

  // Open the decoder.
  AVCodecContext *codec_context = avcodec_alloc_context3(decoder);
  if (avcodec_open2(codec_context, decoder, NULL) < 0) {
    fprintf(stderr, "Could not open decoder\n");
    return 1;
  }

  // Create a frame to store the decoded video frame.
  AVFrame *frame = av_frame_alloc();

  // Get the VAAPI context.
  VAContext *va_context = va_open_display(NULL);
  if (!va_context) {
    fprintf(stderr, "Could not open VAAPI context\n");
    return 1;
  }

  // Find the MJPEG decoder in the VAAPI driver.
  VADecoder *decoder_vaapi = va_find_decoder_by_name(va_context, "mjpeg");
  if (!decoder_vaapi) {
    fprintf(stderr, "Could not find MJPEG decoder in VAAPI driver\n");
    return 1;
  }

  // Create a VASurface to store the decoded video frame.
  VASurface *va_surface = va_surface_create(va_context, video_stream->width, video_stream->height, VA_RT_FORMAT_YUV420);
  if (!va_surface) {
    fprintf(stderr, "Could not create VASurface\n");
    return 1;
  }

  // Start decoding the video stream.
  while (avcodec_decode_video2(codec_context, frame, &got_frame, NULL) >= 0) {
    if (got_frame) {
      // Decode the frame using VAAPI.
      va_render_picture(va_context, decoder_vaapi, va_surface, frame);

      // Do something with the decoded video frame.
    }
  }

  // Close the decoder.
  avcodec_close(codec_context);

  // Close the MJPEG file.
  avformat_close_input(&format_context);

  // Close the VAAPI context.
  va_close_display(va_context);

  return 0;