mirror of
https://github.com/livepeer/lpms
synced 2026-04-22 15:57:25 +08:00
ffmpeg: Support image2 demuxer
This commit is contained in:
+5
-1
@@ -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 = ¶ms->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");
|
||||
|
||||
+33
-1
@@ -97,6 +97,7 @@ type TranscodeOptionsIn struct {
|
||||
Accel Acceleration
|
||||
Device string
|
||||
Transmuxing bool
|
||||
Profile VideoProfile
|
||||
}
|
||||
|
||||
type TranscodeOptions struct {
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+8
-2
@@ -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;
|
||||
|
||||
@@ -51,6 +51,8 @@ typedef struct {
|
||||
char *device;
|
||||
char *xcoderParams;
|
||||
|
||||
// Optional demuxer opts
|
||||
component_opts demuxer;
|
||||
// Optional video decoder + opts
|
||||
component_opts video;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user