Skip to content

Commit

Permalink
ffmpeg: Support image2 demuxer
Browse files Browse the repository at this point in the history
  • Loading branch information
yondonfu authored and j0sh committed Jul 31, 2024
1 parent 3cdfced commit 59d07f5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
6 changes: 5 additions & 1 deletion ffmpeg/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,12 @@ int open_input(input_params *params, struct input_ctx *ctx)
ctx->transmuxing = params->transmuxing;

// open demuxer
ret = avformat_open_input(&ic, inp, NULL, NULL);
AVDictionary **demuxer_opts = NULL;
if (params->demuxer.opts) demuxer_opts = &params->demuxer.opts;
ret = avformat_open_input(&ic, inp, NULL, demuxer_opts);
if (ret < 0) LPMS_ERR(open_input_err, "demuxer: Unable to open input");
// If avformat_open_input replaced the options AVDictionary with options that were not found free it
if (demuxer_opts) av_dict_free(demuxer_opts);
ctx->ic = ic;
ret = avformat_find_stream_info(ic, NULL);
if (ret < 0) LPMS_ERR(open_input_err, "Unable to find input info");
Expand Down
34 changes: 33 additions & 1 deletion ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type TranscodeOptionsIn struct {
Accel Acceleration
Device string
Transmuxing bool
Profile VideoProfile
}

type TranscodeOptions struct {
Expand Down Expand Up @@ -649,6 +650,11 @@ func createCOutputParams(input *TranscodeOptionsIn, ps []TranscodeOptions) ([]C.
// needed for hw dec -> hw rescale -> sw enc
filters = filters + ",hwdownload,format=nv12"
}
if p.Accel == Nvidia && filepath.Ext(input.Fname) == ".png" {
// If the input is PNG image(s) and we are scaling on a Nvidia device
// we need to first convert to a pixel format that the scale_npp filter supports
filters = "format=nv12," + filters
}
// set FPS denominator to 1 if unset by user
if param.FramerateDen == 0 {
param.FramerateDen = 1
Expand Down Expand Up @@ -955,8 +961,34 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
defer C.free(unsafe.Pointer(fname))
xcoderParams := C.CString("")
defer C.free(unsafe.Pointer(xcoderParams))

var demuxerOpts C.component_opts

ext := filepath.Ext(input.Fname)
// If the input has an image file extension setup the image2 demuxer
if ext == ".png" {
image2 := C.CString("image2")
defer C.free(unsafe.Pointer(image2))

demuxerOpts = C.component_opts{
name: image2,
}

if input.Profile.Framerate > 0 {
if input.Profile.FramerateDen == 0 {
input.Profile.FramerateDen = 1
}

// Do not try tofree in this function because in the C code avformat_open_input()
// will destroy this
demuxerOpts.opts = newAVOpts(map[string]string{
"framerate": fmt.Sprintf("%d/%d", input.Profile.Framerate, input.Profile.FramerateDen),
})
}
}

inp := &C.input_params{fname: fname, hw_type: hw_type, device: device, xcoderParams: xcoderParams,
handle: t.handle}
handle: t.handle, demuxer: demuxerOpts}
if input.Transmuxing {
inp.transmuxing = 1
}
Expand Down
10 changes: 8 additions & 2 deletions ffmpeg/transcoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,23 @@ int transcode_init(struct transcode_thread *h, input_params *inp,

if (!inp) LPMS_ERR(transcode_cleanup, "Missing input params")

AVDictionary **demuxer_opts;
if (inp->demuxer.opts) demuxer_opts = &inp->demuxer.opts;

// by default we re-use decoder between segments of same stream
// unless we are using SW deocder and had to re-open IO or demuxer
if (!ictx->ic) {
// reopen demuxer for the input segment if needed
// XXX could open_input() be re-used here?
ret = avformat_open_input(&ictx->ic, inp->fname, NULL, NULL);
ret = avformat_open_input(&ictx->ic, inp->fname, NULL, demuxer_opts);
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to reopen demuxer");
// If avformat_open_input replaced the options AVDictionary with options that were not found free it
if (demuxer_opts) av_dict_free(demuxer_opts);
ret = avformat_find_stream_info(ictx->ic, NULL);
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to find info for reopened stream")
} else if (!ictx->ic->pb) {
} else if (is_mpegts(ictx->ic) && !ictx->ic->pb) {
// reopen input segment file IO context if needed
// only necessary for mpegts
ret = avio_open(&ictx->ic->pb, inp->fname, AVIO_FLAG_READ);
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to reopen file");
} else reopen_decoders = 0;
Expand Down
2 changes: 2 additions & 0 deletions ffmpeg/transcoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ typedef struct {
char *device;
char *xcoderParams;

// Optional demuxer opts
component_opts demuxer;
// Optional video decoder + opts
component_opts video;

Expand Down

0 comments on commit 59d07f5

Please sign in to comment.