|
@@ -1,140 +0,0 @@
|
|
-#include <stdio.h>
|
|
|
|
-
|
|
|
|
-extern "C" {
|
|
|
|
- #include <libavcodec/avcodec.h>
|
|
|
|
- #include <libavformat/avformat.h>
|
|
|
|
- #include <libswscale/swscale.h>
|
|
|
|
- #include <inttypes.h>
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-bool load_frame(const char* filename, int* width, int* height, unsigned char** data)
|
|
|
|
-{
|
|
|
|
-
|
|
|
|
- AVFormatContext* av_format_context = avformat_alloc_context();
|
|
|
|
- if (!av_format_context) {
|
|
|
|
- fprintf(stderr, "could not allocate AVFormatContext.\n");
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- if (avformat_open_input(&av_format_context, filename, NULL, NULL) ){
|
|
|
|
- fprintf(stderr, "could not open video file. %s\n", filename);
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int video_stream_index = -1;
|
|
|
|
- bool found = false;
|
|
|
|
- AVCodec *av_codec;
|
|
|
|
- AVCodecParameters *av_codec_params;
|
|
|
|
- for (int i=0; i < av_format_context->nb_streams; ++i) {
|
|
|
|
- auto stream = av_format_context->streams[i];
|
|
|
|
- av_codec_params = av_format_context->streams[i]->codecpar;
|
|
|
|
- av_codec = avcodec_find_decoder(av_codec_params->codec_id);
|
|
|
|
-
|
|
|
|
- printf("Looking at stream: %d.\n", i);
|
|
|
|
- if (av_codec_params->codec_type == AVMEDIA_TYPE_VIDEO) {
|
|
|
|
- printf("Found video stream\n");
|
|
|
|
- video_stream_index = i;
|
|
|
|
- found = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (found) {
|
|
|
|
- video_stream_index = i;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!found) {
|
|
|
|
- fprintf(stderr, "could not found video stream.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- AVCodecContext *av_codec_context = avcodec_alloc_context3(av_codec);
|
|
|
|
- if (!av_codec_context) {
|
|
|
|
- fprintf(stderr, "could not allocate avcodec context.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(avcodec_parameters_to_context(av_codec_context, av_codec_params) < 0) {
|
|
|
|
- fprintf(stderr, "could not initialize AVCodecContext.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (avcodec_open2(av_codec_context, av_codec, NULL) < 0) {
|
|
|
|
- fprintf(stderr, "could not open codec.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- AVFrame *av_frame = av_frame_alloc();
|
|
|
|
- if (!av_frame) {
|
|
|
|
- fprintf(stderr, "could not allocate av frame.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- AVPacket *av_packet = av_packet_alloc();
|
|
|
|
- if (!av_packet) {
|
|
|
|
- fprintf(stderr, "could not allocate av packet.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int response = -1;
|
|
|
|
- while (av_read_frame(av_format_context, av_packet) >= 0) {
|
|
|
|
- if(av_packet->stream_index != video_stream_index){
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- response = avcodec_send_packet(av_codec_context, av_packet);
|
|
|
|
- if (response < 0) {
|
|
|
|
- fprintf(stderr, "failed to decode packet [1].\n");
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- response = avcodec_receive_frame(av_codec_context, av_frame);
|
|
|
|
- if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
|
|
|
|
- continue;
|
|
|
|
- } else if (response < 0) {
|
|
|
|
- //fprintf(stderr, "failed to decode packet: %s\n.", av_err2str(response));
|
|
|
|
- fprintf(stderr, "failed to decode packet [2].\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- av_packet_unref(av_packet);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- uint8_t *data_in = new uint8_t[av_frame->width * av_frame->height * 4];
|
|
|
|
-
|
|
|
|
- SwsContext *sws_scaler_ctx = sws_getContext(av_frame->width,
|
|
|
|
- av_frame->height,
|
|
|
|
- av_codec_context->pix_fmt,
|
|
|
|
- av_frame->width,
|
|
|
|
- av_frame->height,
|
|
|
|
- AV_PIX_FMT_RGB0,
|
|
|
|
- SWS_BILINEAR,
|
|
|
|
- NULL,
|
|
|
|
- NULL,
|
|
|
|
- NULL);
|
|
|
|
-
|
|
|
|
- if (!sws_scaler_ctx) {
|
|
|
|
- fprintf(stderr, "could not initialize sw scaler context.\n");
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- uint8_t* dest[4] = {data_in, NULL, NULL, NULL};
|
|
|
|
- int dest_linesize[4] = {av_frame->width * 4, 0, 0, 0};
|
|
|
|
- sws_scale(sws_scaler_ctx, av_frame->data, av_frame->linesize, 0, av_frame->height, dest, dest_linesize);
|
|
|
|
- sws_freeContext(sws_scaler_ctx);
|
|
|
|
-
|
|
|
|
- *width = av_frame->width;
|
|
|
|
- *height = av_frame->height;
|
|
|
|
-
|
|
|
|
- *data = data_in;
|
|
|
|
-
|
|
|
|
- avformat_close_input(&av_format_context);
|
|
|
|
- avformat_free_context(av_format_context);
|
|
|
|
- av_frame_free(&av_frame);
|
|
|
|
- av_packet_free(&av_packet);
|
|
|
|
- avcodec_free_context(&av_codec_context);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
-}
|
|
|