network-programmingffmpegiprtppcap

Decoding G.729 using FFMPEG from RTP stream (PCAP)


I have pcap file that contains RTP data which in turn is audio for G.729 codec. Is there a way to decode this stream by pushing it into FFMPEG? This would probably mean I have to extract the RTP payload data from the PCAP file and then somehow pass it to FFMPEG.

Any guidelines and pointers are highly appreciated!


Solution

  • This answer doesn't require ffmpeg, but I assume you dont really care how the audio is extracted... check out How to Decode G729 on the wireshark wiki...

    1. In Wireshark, use menu "Statistics -> RTP -> Show All Streams". Select the desired stream and press "Analyze".

    2. In the next dialog screen, press "Save Payload...". Save options are Format = .raw and Channel = forward. Name file my_input.raw.

    3. Convert the .raw file to .pcm format using the Open G.729 decoder. Syntax: va_g729_decoder.exe my_input.raw my_output.pcm. Or for Linux: wine va_g729_decoder.exe my_input.raw my_output.pcm.

    4. The .pcm file contains 16-bit linear PCM samples at 8000 Hz. Note that each sample is in Little-Endian format. To convert to .au format, all you need to do is prepend the 24-byte au header, and convert each PCM sample to network byte order (or Big-Endian). The following perl script will do the trick.

    USAGE: perl pcm2au.pl [my_inputFile] [my_outputFile]

    $usage = "Usage: 'perl $0 [Source PCM File] [Destination AU File]' ";
    
    $my_inputFile = shift or die $usage;
    $my_outputFile = shift or die $usage;
    
    open(INPUTFILE, "$my_inputFile") or die "Unable to open file: $!\n";
    binmode INPUTFILE;
    
    open(OUTPUTFILE, "> $my_outputFile") or die "Unable to open file: $!\n";
    binmode OUTPUTFILE;
    
    ###################################
    # Write the AU header
    ###################################
    
    print OUTPUTFILE  ".snd";
    
    $foo = pack("CCCC", 0,0,0,24);
    print OUTPUTFILE  $foo;
    
    $foo = pack("CCCC", 0xff,0xff,0xff,0xff);
    print OUTPUTFILE  $foo;
    
    $foo = pack("CCCC", 0,0,0,3);
    print OUTPUTFILE  $foo;
    
    $foo = pack("CCCC", 0,0,0x1f,0x40);
    print OUTPUTFILE  $foo;
    
    $foo = pack("CCCC", 0,0,0,1);
    print OUTPUTFILE  $foo;
    
    #############################
    # swap the PCM samples
    #############################
    
    while (read(INPUTFILE, $inWord, 2) == 2) {
    
        @bytes   = unpack('CC', $inWord);
        $outWord = pack('CC', $bytes[1], $bytes[0]);
        print OUTPUTFILE  $outWord;
    }
    
    close(OUTPUTFILE);
    close(INPUTFILE);