/*
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