#include #include #include #include /* Size of each input chunk to be read and allocate for. */ #ifndef READALL_CHUNK #define READALL_CHUNK 262144 #endif /* This function returns one of the READALL_ constants above. If the return value is zero == READALL_OK, then: (*dataptr) points to a dynamically allocated buffer, with (*sizeptr) chars read from the file. The buffer is allocated for one extra char, which is NUL, and automatically appended after the data. Initial values of (*dataptr) and (*sizeptr) are ignored. */ int readall(FILE *in, uint8_t **dataptr, size_t *sizeptr) { uint8_t *data = NULL, *temp; size_t size = 0; size_t used = 0; size_t n; /* None of the parameters can be NULL. */ if (in == NULL || dataptr == NULL || sizeptr == NULL) { av_log(NULL, AV_LOG_ERROR, "null params %d %d %d\n", in == NULL, dataptr == NULL, sizeptr == NULL); return -1; } /* A read error already occurred? */ if (ferror(in)) { av_log(NULL, AV_LOG_ERROR, "ferror\n"); return -1; } while (1) { if (used + READALL_CHUNK + 1 > size) { size = used + READALL_CHUNK + 1; /* Overflow check. Some ANSI C compilers may optimize this away, though. */ if (size <= used) { free(data); av_log(NULL, AV_LOG_ERROR, "overflow\n"); return -1; } temp = realloc(data, size); if (temp == NULL) { free(data); av_log(NULL, AV_LOG_ERROR, "x\n"); return -1; } data = temp; } n = fread(data + used, 1, READALL_CHUNK, in); if (n == 0) break; used += n; } if (ferror(in)) { free(data); av_log(NULL, AV_LOG_ERROR, "free\n"); return -1; } temp = realloc(data, used + 1); if (temp == NULL) { free(data); av_log(NULL, AV_LOG_ERROR, "temp\n"); return -1; } data = temp; data[used] = '\0'; *dataptr = data; *sizeptr = used; return 0; } // How do I set the AVC config and feed it the raw frame? int main(void) { int ret; FILE *file = fopen("./iframe.raw", "rb"); if (!file) { av_log(NULL, AV_LOG_ERROR, "Could not open file\n"); return -1; } uint8_t *iframe = {0}; size_t iframe_size = 0; if ((ret = readall(file, &iframe, &iframe_size) < 0)) { av_log(NULL, AV_LOG_ERROR, "Could not read file\n"); return ret; } if ((ret = fclose(file) < 0)) { av_log(NULL, AV_LOG_ERROR, "Could not close file\n"); return ret; } printf("A %ld\n", iframe_size); file = fopen("./extradata.raw", "rb"); if (!file) { av_log(NULL, AV_LOG_ERROR, "Could not open file2\n"); return -1; } uint8_t *extradata = {0}; size_t extradata_size = 0; if ((ret = readall(file, &extradata, &extradata_size) < 0)) { av_log(NULL, AV_LOG_ERROR, "Could not read file2\n"); return ret; } if ((ret = fclose(file) < 0)) { av_log(NULL, AV_LOG_ERROR, "Could not close file2\n"); return ret; } printf("B %ld\n", extradata_size); int frame_decoded = 0; AVCodec *dec = avcodec_find_decoder(AV_CODEC_ID_H264); if (!dec) { av_log(NULL, AV_LOG_ERROR, "Could not find decoder\n"); return -1; } AVCodecContext *codec_ctx = avcodec_alloc_context3(dec); if ((ret = avcodec_open2(codec_ctx, dec, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "Could not open video codec: %s\n", av_err2str(ret)); return ret; } // Allocate a codec context for the decoder. AVCodecContext *dec_ctx = avcodec_alloc_context3(dec); if (!dec_ctx) { av_log(NULL, AV_LOG_ERROR, "Could not allocate the codec context\n"); return AVERROR(ENOMEM); } // Configure decoder? dec_ctx->width = 650; dec_ctx->height = 450; dec_ctx->extradata = extradata; dec_ctx->extradata_size = extradata_size; // Does av_packet_from_data require an allocated packet? AVPacket *pkt = av_packet_alloc(); av_packet_from_data(pkt, iframe, iframe_size); // Submit the packet to the decoder. ret = avcodec_send_packet(dec_ctx, pkt); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Could not submit packet for decoding: %d %s\n", ret, av_err2str(ret)); return ret; } // ERROR: Could not submit packet for decoding: -22 Invalid argument // Get all the available frames from the decoder. AVFrame *frame = av_frame_alloc(); while (ret >= 0) { printf("A %d\n", frame_decoded); ret = avcodec_receive_frame(dec_ctx, frame); if (ret < 0) { // Those two return values are special and mean there is no output // frame available, but there were no errors during decoding. if (ret != AVERROR_EOF && ret != AVERROR(EAGAIN)) { av_log(NULL, AV_LOG_ERROR, "Could not decode: %s\n", av_err2str(ret)); return ret; } return 0; } av_frame_unref(frame); if (ret < 0) { return ret; } } return 0; }