Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Hello all!
- I am trying to replicate this ffmpeg command: ffmpeg -i <input> -vn -acodec copy <output>, using the libav APIs.
- There seems to be a lack of updated examples and i really struggled to find any resources.
- I was able to open the file both input and output, allocate format contexts for each, and copy general stream information, but not the packets themselves.
- Here is the code that i gathered with some comments i have added,btw im running it on android :
- ```
- void ffmpeg(
- const char *in_filename,
- const char *out_filename
- ) {
- //Libraries init
- SSL_load_error_strings();
- SSL_library_init();
- av_register_all ();
- avformat_network_init ();
- //Set avlog to log on locat
- av_log_set_callback(log_callback_android);
- AVOutputFormat *ofmt = NULL;
- AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
- AVPacket pkt;
- int ret, i;
- // Opening input file, and checking stream info
- if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not open input file '%s'.Error %s", in_filename, av_err2str(ret));
- goto end;
- }
- if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed to retrieve input stream information");
- goto end;
- }
- //Print stream info
- av_dump_format(ifmt_ctx, 0, in_filename, 0);
- //Allocate new contex for output file
- avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
- if (!ofmt_ctx) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not create output context\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- //Setting output format to inhereted format
- ofmt = ofmt_ctx->oformat;
- // Iterate over all streams in input file
- for (i = 0; i < ifmt_ctx->nb_streams; i++) {
- //Stream input
- AVStream *in_stream = ifmt_ctx->streams[i];
- //Filter non audio streams
- if(in_stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){
- __android_log_print(ANDROID_LOG_INFO,APPNAME,"Audio stream found");
- //in_stream->codec is deprecated, no idea how to get it otherway
- //Making new stream in the output format context, based on the input stream
- AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
- if (!out_stream) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed allocating output stream\n");
- ret = AVERROR_UNKNOWN;
- goto end;
- }
- //Copying stream information to new contex
- ret = avcodec_parameters_copy(out_stream->codecpar,in_stream->codecpar);
- if (ret < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed to copy context from input to output stream codec context\n");
- goto end;
- }
- }
- }
- //Print output format
- av_dump_format(ofmt_ctx, 0, out_filename, 1);
- //Open output file
- if (!(ofmt->flags & AVFMT_NOFILE)) {
- ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
- if (ret < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not open output file '%s'", out_filename);
- goto end;
- }
- }
- //Writing output header
- ret = avformat_write_header(ofmt_ctx, NULL);
- if (ret < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error occurred when opening output file\n");
- goto end;
- }
- //Mux packets - dont know what is happening here, assuming its copying the real data to the streams.
- while (1) {
- AVStream *in_stream, *out_stream;
- ret = av_read_frame(ifmt_ctx, &pkt);
- if (ret < 0)
- break;
- in_stream = ifmt_ctx->streams[pkt.stream_index];
- out_stream = ofmt_ctx->streams[pkt.stream_index];
- log_packet(ifmt_ctx, &pkt, "in");
- //copy packet
- pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_PASS_MINMAX);
- pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_PASS_MINMAX);
- pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
- pkt.pos = -1;
- log_packet(ofmt_ctx, &pkt, "out");
- ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
- if (ret < 0) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error muxing packet\n");
- break;
- }
- av_packet_unref(&pkt);
- }
- av_write_trailer(ofmt_ctx);
- end:
- avformat_close_input(&ifmt_ctx);
- //close output
- if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
- avio_closep(&ofmt_ctx->pb);
- //free output alloc
- avformat_free_context(ofmt_ctx);
- if (ret < 0 && ret != AVERROR_EOF) {
- __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error occurred: %s\n", av_err2str(ret));
- }
- }
- ```
- The muxing packets part,doesnt work, as it failed with signal error, after few iterations - probably error in this code, nothing to do with the libs themselves.
- Here is an ouput of a run:
- ```
- ===Input Information===
- Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '<input>':
- Metadata:
- major_brand :
- isom
- minor_version :
- 512
- compatible_brands:
- isomiso2avc1mp41
- encoder :
- Lavf57.25.100
- Duration:
- 00:00:58.82
- , start:
- 0.000000
- , bitrate:
- 7369 kb/s
- Stream #0:0
- (eng)
- Audio: aac (mp4a / 0x6134706D), 44100 Hz, 2 channels, 160 kb/s
- (default)
- Metadata:
- handler_name :
- SoundHandler
- Stream #0:1
- (eng)
- Video: h264 (avc1 / 0x31637661), none, 640x640, 7213 kb/s
- 30 fps,
- 30 tbr,
- 15360 tbn,
- 15360 tbc
- (default)
- Metadata:
- handler_name :
- VideoHandler
- ===Ouput Information===
- Audio stream found
- Output #0, adts, to 'out.aac':
- Stream #0:0
- Audio: aac (mp4a / 0x6134706D), 44100 Hz, 2 channels, 160 kb/s
- ==Packet Logging==
- in: pts:-2048 pts_time:-0.0464399 dts:-2048 dts_time:-0.0464399 duration:1024 duration_time:0.02322 stream_index:0
- out: pts:-2048 pts_time:-0.0464399 dts:-2048 dts_time:-0.0464399 duration:1024 duration_time:0.02322 stream_index:0
- in: pts:-1024 pts_time:-0.02322 dts:-1024 dts_time:-0.02322 duration:1024 duration_time:0.02322 stream_index:0
- out: pts:-1024 pts_time:-0.02322 dts:-1024 dts_time:-0.02322 duration:1024 duration_time:0.02322 stream_index:0
- in: pts:0 pts_time:0 dts:0 dts_time:0 duration:1024 duration_time:0.02322 stream_index:0
- out: pts:0 pts_time:0 dts:0 dts_time:0 duration:1024 duration_time:0.02322 stream_index:0
- in: pts:0 pts_time:0 dts:0 dts_time:0 duration:512 duration_time:0.0333333 stream_index:1
- Error is
- Signal: SIGSEGV (signal SIGSEGV: invalid address (fault address: 0x29))
- ```
- I would like to get some help for the last part, how to correctly copy the packets, and also how to not use `in_stream->codec->codec`,since it is deprecated, but i couldn’t find a way to use with codecpar
- I was able to retrieve the codec id, but couldn’t find a way to recive an AVcodec instance from it.
- Cheers.
- David Barishev.
Add Comment
Please, Sign In to add comment