Guest User

Copying audio stream

a guest
Mar 28th, 2017
34
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Hello all!
  2. I am trying to replicate this ffmpeg command: ffmpeg -i <input> -vn -acodec copy <output>, using the libav APIs.
  3.  
  4. There seems to be a lack of updated examples and i really struggled to find any resources.
  5. 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.
  6.  
  7. Here is the code that i gathered with some comments i have added,btw im running it on android :
  8. ```
  9. void ffmpeg(
  10.             const char *in_filename,
  11.             const char *out_filename
  12.     ) {
  13.  
  14.         //Libraries init
  15.         SSL_load_error_strings();
  16.         SSL_library_init();
  17.  
  18.         av_register_all ();
  19.         avformat_network_init ();
  20.  
  21.         //Set avlog to log on locat
  22.         av_log_set_callback(log_callback_android);
  23.  
  24.         AVOutputFormat *ofmt = NULL;
  25.         AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
  26.         AVPacket pkt;
  27.         int ret, i;
  28.  
  29.         // Opening input file, and checking stream info
  30.         if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
  31.             __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not open input file '%s'.Error %s", in_filename, av_err2str(ret));
  32.             goto end;
  33.         }
  34.         if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
  35.             __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed to retrieve input stream information");
  36.             goto end;
  37.         }
  38.  
  39.         //Print stream info
  40.         av_dump_format(ifmt_ctx, 0, in_filename, 0);
  41.  
  42.  
  43.         //Allocate new contex for output file
  44.         avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
  45.         if (!ofmt_ctx) {
  46.             __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not create output context\n");
  47.             ret = AVERROR_UNKNOWN;
  48.             goto end;
  49.         }
  50.  
  51.         //Setting output format to inhereted format
  52.         ofmt = ofmt_ctx->oformat;
  53.  
  54.         // Iterate over all streams in input file
  55.         for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  56.             //Stream input
  57.             AVStream *in_stream = ifmt_ctx->streams[i];
  58.  
  59.             //Filter non audio streams
  60.             if(in_stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){
  61.                 __android_log_print(ANDROID_LOG_INFO,APPNAME,"Audio stream found");
  62.  
  63.                 //in_stream->codec is deprecated, no idea how to get it otherway
  64.                 //Making new stream in the output format context, based on the input stream
  65.                 AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
  66.                 if (!out_stream) {
  67.                     __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed allocating output stream\n");
  68.                     ret = AVERROR_UNKNOWN;
  69.                     goto end;
  70.                 }
  71.  
  72.                 //Copying stream information to new contex
  73.                 ret = avcodec_parameters_copy(out_stream->codecpar,in_stream->codecpar);
  74.                 if (ret < 0) {
  75.                     __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed to copy context from input to output stream codec context\n");
  76.                     goto end;
  77.                 }
  78.  
  79.             }
  80.  
  81.         }
  82.         //Print output format
  83.         av_dump_format(ofmt_ctx, 0, out_filename, 1);
  84.  
  85.         //Open output file
  86.         if (!(ofmt->flags & AVFMT_NOFILE)) {
  87.             ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
  88.             if (ret < 0) {
  89.                 __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Could not open output file '%s'", out_filename);
  90.                 goto end;
  91.             }
  92.         }
  93.  
  94.         //Writing output header
  95.         ret = avformat_write_header(ofmt_ctx, NULL);
  96.         if (ret < 0) {
  97.             __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error occurred when opening output file\n");
  98.             goto end;
  99.         }
  100.  
  101.         //Mux packets - dont know what is happening here, assuming its copying the real data to the streams.
  102.         while (1) {
  103.             AVStream *in_stream, *out_stream;
  104.             ret = av_read_frame(ifmt_ctx, &pkt);
  105.             if (ret < 0)
  106.                 break;
  107.  
  108.             in_stream  = ifmt_ctx->streams[pkt.stream_index];
  109.             out_stream = ofmt_ctx->streams[pkt.stream_index];
  110.             log_packet(ifmt_ctx, &pkt, "in");
  111.             //copy packet
  112.             pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_PASS_MINMAX);
  113.             pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_PASS_MINMAX);
  114.             pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
  115.             pkt.pos = -1;
  116.             log_packet(ofmt_ctx, &pkt, "out");
  117.             ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
  118.             if (ret < 0) {
  119.                 __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error muxing packet\n");
  120.                 break;
  121.             }
  122.             av_packet_unref(&pkt);
  123.         }
  124.         av_write_trailer(ofmt_ctx);
  125.  
  126.         end:
  127.         avformat_close_input(&ifmt_ctx);
  128.         //close output
  129.         if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
  130.             avio_closep(&ofmt_ctx->pb);
  131.         //free output alloc
  132.         avformat_free_context(ofmt_ctx);
  133.         if (ret < 0 && ret != AVERROR_EOF) {
  134.             __android_log_print(ANDROID_LOG_ERROR, APPNAME, "Error occurred: %s\n", av_err2str(ret));
  135.  
  136.         }
  137.     }
  138. ```
  139. 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.
  140.  
  141. Here is an ouput of a run:
  142. ```
  143. ===Input Information===
  144.  
  145.     Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '<input>':
  146.       Metadata:
  147.         major_brand     :
  148.             isom
  149.         minor_version   :
  150.             512
  151.         compatible_brands:
  152.             isomiso2avc1mp41
  153.         encoder         :
  154.             Lavf57.25.100
  155.         Duration:
  156.             00:00:58.82
  157.             , start:
  158.             0.000000
  159.             , bitrate:
  160.         7369 kb/s
  161.             Stream #0:0
  162.                 (eng)
  163.                     Audio: aac (mp4a / 0x6134706D), 44100 Hz, 2 channels, 160 kb/s
  164.                 (default)
  165.             Metadata:
  166.             handler_name    :
  167.                 SoundHandler
  168.             Stream #0:1
  169.                 (eng)
  170.                     Video: h264 (avc1 / 0x31637661), none, 640x640, 7213 kb/s
  171.  
  172.                 30 fps,
  173.                 30 tbr,
  174.                 15360 tbn,
  175.                 15360 tbc
  176.                 (default)
  177.             Metadata:
  178.             handler_name    :
  179.             VideoHandler
  180.  
  181.     ===Ouput Information===
  182.  
  183.     Audio stream found
  184.     Output #0, adts, to 'out.aac':
  185.         Stream #0:0
  186.     Audio: aac (mp4a / 0x6134706D), 44100 Hz, 2 channels, 160 kb/s
  187.  
  188.     ==Packet Logging==
  189.  
  190.     in: pts:-2048 pts_time:-0.0464399 dts:-2048 dts_time:-0.0464399 duration:1024 duration_time:0.02322 stream_index:0
  191.     out: pts:-2048 pts_time:-0.0464399 dts:-2048 dts_time:-0.0464399 duration:1024 duration_time:0.02322 stream_index:0
  192.     in: pts:-1024 pts_time:-0.02322 dts:-1024 dts_time:-0.02322 duration:1024 duration_time:0.02322 stream_index:0
  193.     out: pts:-1024 pts_time:-0.02322 dts:-1024 dts_time:-0.02322 duration:1024 duration_time:0.02322 stream_index:0
  194.     in: pts:0 pts_time:0 dts:0 dts_time:0 duration:1024 duration_time:0.02322 stream_index:0
  195.     out: pts:0 pts_time:0 dts:0 dts_time:0 duration:1024 duration_time:0.02322 stream_index:0
  196.     in: pts:0 pts_time:0 dts:0 dts_time:0 duration:512 duration_time:0.0333333 stream_index:1
  197.  
  198. Error is
  199. Signal: SIGSEGV (signal SIGSEGV: invalid address (fault address: 0x29))
  200. ```
  201. 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
  202. I was able to retrieve the codec id, but couldn’t find a way to recive an AVcodec instance from it.
  203.  
  204. Cheers.
  205. David Barishev.
RAW Paste Data