RyanMarcus icon

decoder.cpp

RyanMarcus | PRO | 01/18/16 08:27:39 PM UTC | 0 ⭐ | 375 👁️ | Never ⏰ | []
C |

4.21 KB

|

None

|

0 👍

/

0 👎

/*
Program output:
 
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fa75080c200] stream 0, timescale not set
[mjpeg @ 0x7fa751000c00] Changeing bps to 8
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.m4a':
  Metadata:
    major_brand     : M4A 
    minor_version   : 0
    compatible_brands: M4A mp42isom
    creation_time   : 2029-10-02 09:03:14
    title           : Heartsigh
    artist          : Purity Ring
    album_artist    : Purity Ring
    album           : Another Eternity
    genre           : Synth-pop
    composer        : Corin Roddick
    track           : 1/10
    disc            : 1/1
    date            : 2015
    encoder         : X Lossless Decoder 20141129a, QuickTime 7.7.3
  Duration: 00:03:19.14, start: 0.000000, bitrate: 2962 kb/s
    Stream #0:0(eng): Audio: alac (alac / 0x63616C61), 96000 Hz, stereo, s32p (24 bit), 2955 kb/s (default)
    Metadata:
      creation_time   : 2029-10-02 09:03:14
    Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 1000x1000 [SAR 72:72 DAR 1:1], 90k tbr, 90k tbn, 90k tbc
Using codec: ALAC (Apple Lossless Audio Codec) for stream 0
[alac @ 0x7fa750808a00] extradata is too small
could not open codec
error: Invalid data found when processing input
 
*/
 
 
#include <stdio.h>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}
//#include <ffmpeg/swscale.h>
 
void printError(int err) {
    char buf[300];
    if (av_strerror(err, buf, 300) < 0) {
        printf("unknown error code: %d\n", err);
    } else {
        printf("error: %s\n", buf);
    }
}
 
 
 
int main(int argc, char** argv) {
 
    // register all the needed ffmpeg formats and codecs...
    av_register_all();
 
    AVFormatContext* pFormatCtx = NULL;
 
    if (avformat_open_input(&pFormatCtx, "test.m4a", NULL, NULL) != 0) {
        printf("error: couldn't open file.\n");
        return -1;
    }
 
    if (avformat_find_stream_info(pFormatCtx, NULL) != 0) {
        printf("error: couldn't find stream information\n");
        return -1;
    }
 
    // dump debugging info about the stream
    av_dump_format(pFormatCtx, 0, "test.m4a", 0);
    
    // figure out which stream is the "best" stream
    AVCodec* codec;
    int firstAudio = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
 
    if (firstAudio == AVERROR_STREAM_NOT_FOUND) {
        printf("could not find an audio stream\n");
        return -1;
    } else if (firstAudio == AVERROR_DECODER_NOT_FOUND) {
        printf("found an audio stream, but no decoder\n");
        return -1;
    } else if (firstAudio < 0) {
        printf("error finding audio stream and codec\n");
        return -1;
    }
    
    
    printf("Using codec: %s for stream %d\n", codec->long_name, firstAudio);
 
    AVCodecContext* pCodecCtx = avcodec_alloc_context3(codec);
 
 
    
    if (pCodecCtx == NULL) {
        printf("could not allocate a codec context\n");
        return -1;
    }
    
    int err;
    if ((err = avcodec_open2(pCodecCtx, codec, NULL)) != 0) {
        printf("could not open codec\n");
        printError(err);
        return -1;
    }
 
 
 
    /*
         PROGRAM DIES ABOVE
     */
 
 
 
 
 
 
    
    int bytesPerSample = av_get_bytes_per_sample(pCodecCtx->sample_fmt);
    if (bytesPerSample <= 0) {
        printf("could not determine proper number of bytes per sample\n");
        return -1;
    }
    printf("Bytes per sample: %d\n", bytesPerSample);
    
    AVFrame *pFrame = av_frame_alloc();
    AVPacket packet;
    av_init_packet(&packet);
 
    int bufferSize = 20480 + FF_INPUT_BUFFER_PADDING_SIZE;
    uint8_t buffer[bufferSize];
    packet.data = buffer;
    packet.size = bufferSize;
 
    
    while (av_read_frame(pFormatCtx, &packet) >= 0) {
        if (packet.stream_index != firstAudio)
            continue;
 
        // decode a frame
        int totalRead = 0;
        while (totalRead <= packet.size) {
            int gotFrame, read = 0;
            read += avcodec_decode_audio4(pCodecCtx, pFrame, &gotFrame, &packet);
 
            if (read < 0) {
                printf("error during decoding\n");
                printError(read);
                return -1;
            }
            
            printf("%d\n", gotFrame);
            if (gotFrame == 0)
                continue;
            totalRead += read;
            printf("%d / %d\n", totalRead, packet.size);
            
            for (int i = 0; i < pFrame->nb_samples; i++) {
                for (int ch = 0; ch < pCodecCtx->channels; ch++) {
                    //print the first byte of each sample...
                    printf("%d\n", pFrame->data[ch][i]);
                }
            }
        }
    }
 
 
 
 
 
    
 
    
 
 
 
}

Comments