mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-12 16:14:44 +08:00
feat(*): added support for copying audio/subtitle streams and pause/abort (#1179)
* feat: added Makefile target for debian * fix: fixed Dockerfile installing the wrong package * feat: added hwaccel for encoder and decoder * feat: added benchmark mode * feat: removed hard-coded keyframe info * chore: cleaned up headers and organized code * style: cleaned up headers and includes * feat: added a progress bar for CLI * feat: removed atomicity requirements on processed frames * feat: added pause and abort for CLI * chore: updated default preset and crf settings * feat: added support for copying audio and subtitle streams * fix: fixed syntax issues for MSVC * fix: fixed audio/subtitle timestamp rescaling Signed-off-by: k4yt3x <i@k4yt3x.com>
This commit is contained in:
@@ -1,19 +1,25 @@
|
||||
#include "decoder.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavfilter/avfilter.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/rational.h>
|
||||
static enum AVPixelFormat hw_pix_fmt = AV_PIX_FMT_NONE;
|
||||
|
||||
// Callback function to choose the hardware-accelerated pixel format
|
||||
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx, const enum AVPixelFormat *pix_fmts) {
|
||||
for (const enum AVPixelFormat *p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
if (*p == hw_pix_fmt) {
|
||||
return *p;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
int init_decoder(
|
||||
AVHWDeviceType hw_type,
|
||||
AVBufferRef *hw_ctx,
|
||||
const char *input_filename,
|
||||
AVFormatContext **fmt_ctx,
|
||||
AVCodecContext **dec_ctx,
|
||||
@@ -44,18 +50,45 @@ int init_decoder(
|
||||
AVStream *video_stream = ifmt_ctx->streams[stream_index];
|
||||
|
||||
// Set up the decoder
|
||||
const AVCodec *dec = avcodec_find_decoder(video_stream->codecpar->codec_id);
|
||||
if (!dec) {
|
||||
const AVCodec *decoder = avcodec_find_decoder(video_stream->codecpar->codec_id);
|
||||
if (!decoder) {
|
||||
fprintf(stderr, "Failed to find decoder for stream #%u\n", stream_index);
|
||||
return AVERROR_DECODER_NOT_FOUND;
|
||||
}
|
||||
|
||||
codec_ctx = avcodec_alloc_context3(dec);
|
||||
codec_ctx = avcodec_alloc_context3(decoder);
|
||||
if (!codec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate the decoder context\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
// Set hardware device context
|
||||
if (hw_ctx != nullptr) {
|
||||
codec_ctx->hw_device_ctx = av_buffer_ref(hw_ctx);
|
||||
codec_ctx->get_format = get_hw_format;
|
||||
|
||||
// Automatically determine the hardware pixel format
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||
if (config == nullptr) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Decoder %s does not support device type %s.\n",
|
||||
decoder->name,
|
||||
av_hwdevice_get_type_name(hw_type)
|
||||
);
|
||||
avcodec_free_context(&codec_ctx);
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == hw_type) {
|
||||
hw_pix_fmt = config->pix_fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret = avcodec_parameters_to_context(codec_ctx, video_stream->codecpar)) < 0) {
|
||||
fprintf(stderr, "Failed to copy decoder parameters to input decoder context\n");
|
||||
return ret;
|
||||
@@ -66,7 +99,7 @@ int init_decoder(
|
||||
codec_ctx->pkt_timebase = video_stream->time_base;
|
||||
codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, video_stream, NULL);
|
||||
|
||||
if ((ret = avcodec_open2(codec_ctx, dec, NULL)) < 0) {
|
||||
if ((ret = avcodec_open2(codec_ctx, decoder, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open decoder for stream #%u\n", stream_index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user