Skip to content

Commit de94555

Browse files
committed
ffmpeg: Support image2 demuxer
1 parent 481c24f commit de94555

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

ffmpeg/decoder.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,12 @@ int open_input(input_params *params, struct input_ctx *ctx)
338338
ctx->transmuxing = params->transmuxe;
339339

340340
// open demuxer
341-
ret = avformat_open_input(&ic, inp, NULL, NULL);
341+
AVDictionary **demuxer_opts = NULL;
342+
if (params->demuxer.opts) demuxer_opts = &params->demuxer.opts;
343+
ret = avformat_open_input(&ic, inp, NULL, demuxer_opts);
342344
if (ret < 0) LPMS_ERR(open_input_err, "demuxer: Unable to open input");
345+
// If avformat_open_input replaced the options AVDictionary with options that were not found free it
346+
if (demuxer_opts) av_dict_free(demuxer_opts);
343347
ctx->ic = ic;
344348
ret = avformat_find_stream_info(ic, NULL);
345349
if (ret < 0) LPMS_ERR(open_input_err, "Unable to find input info");

ffmpeg/ffmpeg.go

+33-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ type TranscodeOptionsIn struct {
9797
Accel Acceleration
9898
Device string
9999
Transmuxing bool
100+
Profile VideoProfile
100101
}
101102

102103
type TranscodeOptions struct {
@@ -649,6 +650,11 @@ func createCOutputParams(input *TranscodeOptionsIn, ps []TranscodeOptions) ([]C.
649650
// needed for hw dec -> hw rescale -> sw enc
650651
filters = filters + ",hwdownload,format=nv12"
651652
}
653+
if p.Accel == Nvidia && filepath.Ext(input.Fname) == ".png" {
654+
// If the input is PNG image(s) and we are scaling on a Nvidia device
655+
// we need to first convert to a pixel format that the scale_npp filter supports
656+
filters = "format=nv12," + filters
657+
}
652658
// set FPS denominator to 1 if unset by user
653659
if param.FramerateDen == 0 {
654660
param.FramerateDen = 1
@@ -955,8 +961,34 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
955961
defer C.free(unsafe.Pointer(fname))
956962
xcoderParams := C.CString("")
957963
defer C.free(unsafe.Pointer(xcoderParams))
964+
965+
var demuxerOpts C.component_opts
966+
967+
ext := filepath.Ext(input.Fname)
968+
// If the input has an image file extension setup the image2 demuxer
969+
if ext == ".png" {
970+
image2 := C.CString("image2")
971+
defer C.free(unsafe.Pointer(image2))
972+
973+
demuxerOpts = C.component_opts{
974+
name: image2,
975+
}
976+
977+
if input.Profile.Framerate > 0 {
978+
if input.Profile.FramerateDen == 0 {
979+
input.Profile.FramerateDen = 1
980+
}
981+
982+
// Do not try tofree in this function because in the C code avformat_open_input()
983+
// will destroy this
984+
demuxerOpts.opts = newAVOpts(map[string]string{
985+
"framerate": fmt.Sprintf("%d/%d", input.Profile.Framerate, input.Profile.FramerateDen),
986+
})
987+
}
988+
}
989+
958990
inp := &C.input_params{fname: fname, hw_type: hw_type, device: device, xcoderParams: xcoderParams,
959-
handle: t.handle}
991+
handle: t.handle, demuxer: demuxerOpts}
960992
if input.Transmuxing {
961993
inp.transmuxe = 1
962994
}

ffmpeg/transcoder.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,23 @@ int transcode_init(struct transcode_thread *h, input_params *inp,
160160

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

163+
AVDictionary **demuxer_opts;
164+
if (inp->demuxer.opts) demuxer_opts = &inp->demuxer.opts;
165+
163166
// by default we re-use decoder between segments of same stream
164167
// unless we are using SW deocder and had to re-open IO or demuxer
165168
if (!ictx->ic) {
166169
// reopen demuxer for the input segment if needed
167170
// XXX could open_input() be re-used here?
168-
ret = avformat_open_input(&ictx->ic, inp->fname, NULL, NULL);
171+
ret = avformat_open_input(&ictx->ic, inp->fname, NULL, demuxer_opts);
169172
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to reopen demuxer");
173+
// If avformat_open_input replaced the options AVDictionary with options that were not found free it
174+
if (demuxer_opts) av_dict_free(demuxer_opts);
170175
ret = avformat_find_stream_info(ictx->ic, NULL);
171176
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to find info for reopened stream")
172-
} else if (!ictx->ic->pb) {
177+
} else if (is_mpegts(ictx->ic) && !ictx->ic->pb) {
173178
// reopen input segment file IO context if needed
179+
// only necessary for mpegts
174180
ret = avio_open(&ictx->ic->pb, inp->fname, AVIO_FLAG_READ);
175181
if (ret < 0) LPMS_ERR(transcode_cleanup, "Unable to reopen file");
176182
} else reopen_decoders = 0;

ffmpeg/transcoder.h

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ typedef struct {
5151
char *device;
5252
char *xcoderParams;
5353

54+
// Optional demuxer opts
55+
component_opts demuxer;
5456
// Optional video decoder + opts
5557
component_opts video;
5658

0 commit comments

Comments
 (0)