Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重新封装,不做解编码 #86

Closed
xingsongs opened this issue Apr 12, 2022 · 8 comments · Fixed by #87
Closed

重新封装,不做解编码 #86

xingsongs opened this issue Apr 12, 2022 · 8 comments · Fixed by #87
Assignees

Comments

@xingsongs
Copy link

想用rsmpeg 实现下面的功能,因为ffmpeg 是lgpl 协议所有没有libx264 依赖。
./ffmpeg -r 30 -i xxxx.h264 -c:v copy -f mp4 xxxxx.mp4

基于tests/avio_writing.rs 删除了decode 和encode 部分, 但是无法通过 AVframe去设置 pts 时间,导致程序报错,请给一些建议。
image

图片来自此连接-章节2-重新封装

@ldm0 ldm0 self-assigned this Apr 12, 2022
@ldm0
Copy link
Member

ldm0 commented Apr 12, 2022

Check https://github.com/leandromoreira/ffmpeg-libav-tutorial/blob/master/2_remuxing.c

直接从packet里可以拿到pts

@xingsongs
Copy link
Author

是从 input_format_context.read_packet() 拿的packet 里面有 pts, 直接output_format_context.write_frame 写进去?

image

`fn main() {

// std::fs::create_dir_all("output/avio_muxing/").unwrap();
transcoding(
    cstr!("./1649399982562-123131231-3002-called.h264"),
    cstr!("./xxxx.mp4"),
)
.unwrap();

}

/// Get video_stream_index, input_format_context, decode_context.
fn open_input_file(filename: &CStr) -> Result<(AVFormatContextInput)> {
let mut input_format_context = AVFormatContextInput::open(filename)?;
input_format_context.dump(0, filename)?;

Ok((input_format_context))

}

/// Return output_format_context and encode_context
fn open_output_file(
filename: &CStr,
input_format_context: &AVFormatContextInput,
) -> Result<(AVFormatContextOutput)> {
let mut output_format_context = AVFormatContextOutput::create(filename, None)?;

let number_of_streams = input_format_context.nb_streams as usize;

let stream_index = 0;

let mut streams_list: Vec<i32> = vec![Default::default(); number_of_streams];

for i in 0..number_of_streams {
    let in_stream = input_format_context.streams().get(i as usize).unwrap();

    streams_list[i] += stream_index;
    let mut out_stream = output_format_context.new_stream();
    let dd = in_stream.codecpar();

    let cc = dd.deref();

    out_stream.set_codecpar(cc.clone())
}

output_format_context.dump(0, filename)?;
output_format_context.write_header()?;

Ok((output_format_context))

}

/// Transcoding audio and video stream in a multi media file.
pub fn transcoding(input_file: &CStr, output_file: &CStr) -> Result<()> {
let mut input_format_context = open_input_file(input_file)?;
let mut output_format_context = open_output_file(output_file, &input_format_context)?;

loop {
    let mut packet = match input_format_context.read_packet() {
        Ok(Some(x)) => x,
        // No more frames
        Ok(None) => break,
        Err(e) => bail!("Read frame error: {:?}", e),
    };

    {
        packet.rescale_ts(
            input_format_context
                .streams()
                .get(packet.stream_index.try_into().unwrap())
                .unwrap()
                .time_base,
            output_format_context
                .streams()
                .get(packet.stream_index.try_into().unwrap())
                .unwrap()
                .time_base,
        );
    }

    match output_format_context.write_frame(&mut packet) {
        Ok(()) => Ok(()),
        Err(RsmpegError::InterleavedWriteFrameError(-22)) => Ok(()),
        Err(e) => Err(e),
    }
    .context("Interleaved write frame failed.")?;
}

output_format_context.write_trailer()?;
Ok(())

}`

@ldm0
Copy link
Member

ldm0 commented Apr 12, 2022

不能直写,要根据input stream和output stream的time_base缩放,可以参考上面给的C源码,av_rescale_q_rndav_rescale_q在rsmpeg里都提供了。

@ldm0
Copy link
Member

ldm0 commented Apr 12, 2022

BTW

因为ffmpeg 是lgpl 协议所有没有libx264 依赖

可以在脚本里给configure参数加上--enable-gpl 和 --enable-libx264,再单独编一个x264链接上。

@xingsongs xingsongs reopened this Apr 12, 2022
@xingsongs
Copy link
Author

@xingsongs xingsongs reopened this Apr 12, 2022
@xingsongs
Copy link
Author

不能直写,要根据input stream和output stream的time_base缩放,可以参考上面给的C源码,av_rescale_q_rndav_rescale_q在rsmpeg里都提供了。

这样写还是不好用
image

@xingsongs
Copy link
Author

BTW

因为ffmpeg 是lgpl 协议所有没有libx264 依赖

可以在脚本里给configure参数加上--enable-gpl 和 --enable-libx264,再单独编一个x264链接上。

gpl 过不了公司的blackduck

@ldm0
Copy link
Member

ldm0 commented Apr 12, 2022

这样写还是不好用

问题不大,我加几个setter吧。

@ldm0 ldm0 closed this as completed in #87 Apr 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants