add files
This commit is contained in:
parent
baf6b16891
commit
6ac46273bb
|
@ -0,0 +1,375 @@
|
|||
|
||||
#include <Eina.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
FFmpeg *
|
||||
ff_new(void)
|
||||
{
|
||||
FFmpeg *ff;
|
||||
|
||||
ff = (FFmpeg*)calloc(1, sizeof(FFmpeg));
|
||||
if (!ff)
|
||||
return NULL;
|
||||
|
||||
ff->videos = eina_array_new(1);
|
||||
if (!ff->videos)
|
||||
goto free_ff;
|
||||
|
||||
ff->audios = eina_array_new(1);
|
||||
if (!ff->audios)
|
||||
goto free_videos;
|
||||
|
||||
return ff;
|
||||
|
||||
free_videos:
|
||||
eina_array_free(ff->videos);
|
||||
free_ff:
|
||||
free(ff);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ff_free(FFmpeg *ff)
|
||||
{
|
||||
if (!ff)
|
||||
return;
|
||||
|
||||
eina_array_free(ff->audios);
|
||||
eina_array_free(ff->videos);
|
||||
free(ff);
|
||||
}
|
||||
|
||||
static void
|
||||
_ff_free_lists(FFmpeg *ff)
|
||||
{
|
||||
Eina_Array_Iterator iterator;
|
||||
void *p;
|
||||
unsigned int i;
|
||||
|
||||
EINA_ARRAY_ITER_NEXT(ff->audios, i, p, iterator)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
eina_array_free(ff->audios);
|
||||
|
||||
EINA_ARRAY_ITER_NEXT(ff->videos, i, p, iterator)
|
||||
{
|
||||
free(p);
|
||||
}
|
||||
eina_array_free(ff->videos);
|
||||
}
|
||||
|
||||
int
|
||||
ff_file_open(FFmpeg *ff, const char *file)
|
||||
{
|
||||
FF_Video *video;
|
||||
int err;
|
||||
unsigned int i;
|
||||
|
||||
if ((!file || !*file))
|
||||
return 0;
|
||||
|
||||
ff->format_ctx = avformat_alloc_context();
|
||||
if (!ff->format_ctx)
|
||||
{
|
||||
printf("ff NULL\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ff->video_index = -1;
|
||||
ff->audio_index = -1;
|
||||
|
||||
/* parse header of the file */
|
||||
err = avformat_open_input(&ff->format_ctx, file, NULL, NULL);
|
||||
if (err)
|
||||
{
|
||||
printf("avformat_open_input() failed");
|
||||
goto free_format_ctx;
|
||||
}
|
||||
|
||||
/* fill format_stx->streams */
|
||||
if (avformat_find_stream_info(ff->format_ctx, NULL) < 0)
|
||||
{
|
||||
printf("avformat_find_stream_info() failed");
|
||||
goto free_format_ctx;
|
||||
}
|
||||
|
||||
printf(" * file name : %s\n", ff->format_ctx->url);
|
||||
printf(" * format name : %s\n", ff->format_ctx->iformat->name);
|
||||
printf(" * duration : %lld\n", ff->format_ctx->duration);
|
||||
printf(" * bitrate : %lld\n", ff->format_ctx->bit_rate);
|
||||
|
||||
for (i = 0; i < ff->format_ctx->nb_streams; i++)
|
||||
{
|
||||
const AVCodecParameters *codec_par;
|
||||
const AVCodec *codec;
|
||||
|
||||
printf(" * stream %d time base : %d/%d\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->time_base.num,
|
||||
ff->format_ctx->streams[i]->time_base.den);
|
||||
printf(" * stream %d r frame rate: %d/%d\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->r_frame_rate.num,
|
||||
ff->format_ctx->streams[i]->r_frame_rate.den);
|
||||
printf(" * stream %d a frame rate: %d/%d\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->avg_frame_rate.num,
|
||||
ff->format_ctx->streams[i]->avg_frame_rate.den);
|
||||
printf(" * stream %d start time: %lld\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->start_time);
|
||||
printf(" * stream %d duration : %lld\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->duration);
|
||||
printf(" * stream %d nb frames : %lld\n",
|
||||
i,
|
||||
ff->format_ctx->streams[i]->nb_frames);
|
||||
|
||||
codec_par = ff->format_ctx->streams[i]->codecpar;
|
||||
codec = avcodec_find_decoder(codec_par->codec_id);
|
||||
|
||||
if (!codec)
|
||||
{
|
||||
printf("unsupported codec, continuing\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (codec_par->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
{
|
||||
video = (FF_Video *)calloc(1, sizeof(FF_Video));
|
||||
if (!video)
|
||||
{
|
||||
printf("fail to allocate memory for video\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
video->codec_par = codec_par;
|
||||
video->codec = codec;
|
||||
video->stream_index = i;
|
||||
eina_array_push(ff->videos, video);
|
||||
|
||||
if (ff->video_index == -1)
|
||||
{
|
||||
ff->video_index = 0;
|
||||
}
|
||||
}
|
||||
else if (codec_par->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
{
|
||||
FF_Audio *audio;
|
||||
|
||||
audio = (FF_Audio *)calloc(1, sizeof(FF_Audio));
|
||||
if (!audio)
|
||||
{
|
||||
printf("fail to allocate memory for audio\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
audio->codec_par = codec_par;
|
||||
audio->codec = codec;
|
||||
audio->stream_index = i;
|
||||
eina_array_push(ff->audios, audio);
|
||||
|
||||
if (ff->audio_index == -1)
|
||||
{
|
||||
ff->audio_index = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ff->video_index == -1)
|
||||
{
|
||||
printf("WARNING : no video stream`n");
|
||||
}
|
||||
|
||||
video = (FF_Video *)eina_array_data_get(ff->videos, ff->video_index);
|
||||
ff->codec_ctx = avcodec_alloc_context3(video->codec);
|
||||
if (!ff->codec_ctx)
|
||||
{
|
||||
goto free_eina_lists;
|
||||
}
|
||||
|
||||
if (avcodec_parameters_to_context(ff->codec_ctx, video->codec_par) < 0)
|
||||
{
|
||||
printf("WARNING : no video stream`n");
|
||||
goto free_codec_ctx;
|
||||
}
|
||||
|
||||
if (avcodec_open2(ff->codec_ctx, video->codec, NULL) < 0)
|
||||
{
|
||||
printf("failed to open codec through avcodec_open2\n");
|
||||
goto free_codec_ctx;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
free_codec_ctx:
|
||||
avcodec_free_context(&ff->codec_ctx);
|
||||
free_eina_lists:
|
||||
_ff_free_lists(ff);
|
||||
free_format_ctx:
|
||||
avformat_free_context(ff->format_ctx);
|
||||
ff->audio_index = -1;
|
||||
ff->video_index = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ff_file_close(FFmpeg *ff)
|
||||
{
|
||||
avcodec_free_context(&ff->codec_ctx);
|
||||
_ff_free_lists(ff);
|
||||
avformat_free_context(ff->format_ctx);
|
||||
ff->audio_index = -1;
|
||||
ff->video_index = -1;
|
||||
}
|
||||
|
||||
void
|
||||
ff_size_get(FFmpeg *ff, int *width, int *height)
|
||||
{
|
||||
FF_Video *v;
|
||||
|
||||
if (width) *width = 0;
|
||||
if (height) *height = 0;
|
||||
if (ff->video_index < 0)
|
||||
return;
|
||||
|
||||
v = (FF_Video *)eina_array_data_get(ff->videos, ff->video_index);
|
||||
|
||||
if (width)
|
||||
{
|
||||
*width = ff->format_ctx->streams[v->stream_index]->codecpar->width;
|
||||
}
|
||||
|
||||
if (height)
|
||||
{
|
||||
*height = ff->format_ctx->streams[v->stream_index]->codecpar->height;
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
ff_len_get(FFmpeg *ff)
|
||||
{
|
||||
/*
|
||||
* get duration of the file, not of the video stream
|
||||
* see https://stackoverflow.com/a/32538549
|
||||
*/
|
||||
return ff->format_ctx->duration / (double)AV_TIME_BASE;
|
||||
}
|
||||
|
||||
int
|
||||
_ff_fps_get(FFmpeg *ff, int *n, int *d)
|
||||
{
|
||||
FF_Video *v;
|
||||
|
||||
if (n) *n = 0;
|
||||
if (d) *d = 0;
|
||||
if (ff->video_index < 0)
|
||||
return 0;
|
||||
|
||||
v = (FF_Video *)eina_array_data_get(ff->videos, ff->video_index);
|
||||
|
||||
if (n)
|
||||
*n = ff->format_ctx->streams[v->stream_index]->avg_frame_rate.num;
|
||||
|
||||
if (d)
|
||||
*d = ff->format_ctx->streams[v->stream_index]->avg_frame_rate.den;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ff_fps_num_get(FFmpeg *ff)
|
||||
{
|
||||
int num;
|
||||
|
||||
_ff_fps_get(ff, &num, NULL);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int
|
||||
ff_fps_den_get(FFmpeg *ff)
|
||||
{
|
||||
int den;
|
||||
|
||||
_ff_fps_get(ff, NULL, &den);
|
||||
|
||||
return den;
|
||||
}
|
||||
|
||||
double
|
||||
ff_fps_get(FFmpeg *ff)
|
||||
{
|
||||
int num, den;
|
||||
|
||||
if (!_ff_fps_get(ff, &num, &den))
|
||||
return 0.0;
|
||||
|
||||
return (double)num / (double)den;
|
||||
}
|
||||
|
||||
int
|
||||
ff_video_handled(FFmpeg *ff)
|
||||
{
|
||||
return ff->video_index >= 0;
|
||||
}
|
||||
|
||||
int
|
||||
ff_audio_handled(FFmpeg *ff)
|
||||
{
|
||||
return ff->audio_index >= 0;
|
||||
}
|
||||
|
||||
int
|
||||
ff_format_get(FFmpeg *ff)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ff_video_channel_count(FFmpeg *ff)
|
||||
{
|
||||
return eina_array_count_get(ff->videos);
|
||||
}
|
||||
|
||||
void
|
||||
ff_video_channel_set(FFmpeg *ff, int channel)
|
||||
{
|
||||
if ((channel >= 0) || (channel < ff_video_channel_count(ff)))
|
||||
{
|
||||
ff->video_index = channel;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ff_video_channel_get(FFmpeg *ff)
|
||||
{
|
||||
return ff->video_index;
|
||||
}
|
||||
|
||||
int
|
||||
ff_audio_channel_count(FFmpeg *ff)
|
||||
{
|
||||
return eina_array_count_get(ff->audios);
|
||||
}
|
||||
|
||||
void
|
||||
ff_audio_channel_set(FFmpeg *ff, int channel)
|
||||
{
|
||||
if ((channel >= 0) || (channel < ff_audio_channel_count(ff)))
|
||||
{
|
||||
ff->audio_index = channel;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ff_audio_channel_get(FFmpeg *ff)
|
||||
{
|
||||
return ff->audio_index;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef FFMPEG_H
|
||||
#define FFMPEG_H
|
||||
|
||||
typedef struct FF_Video FF_Video;
|
||||
typedef struct FF_Audio FF_Audio;
|
||||
typedef struct FFmpeg FFmpeg;
|
||||
|
||||
struct FF_Video
|
||||
{
|
||||
const AVCodecParameters *codec_par;
|
||||
const AVCodec *codec;
|
||||
int stream_index;
|
||||
};
|
||||
|
||||
struct FF_Audio
|
||||
{
|
||||
const AVCodecParameters *codec_par;
|
||||
const AVCodec *codec;
|
||||
int stream_index;
|
||||
};
|
||||
|
||||
struct FFmpeg
|
||||
{
|
||||
AVFormatContext *format_ctx;
|
||||
AVCodecContext *codec_ctx;
|
||||
Eina_Array *videos;
|
||||
Eina_Array *audios;
|
||||
int video_index;
|
||||
int audio_index;
|
||||
};
|
||||
|
||||
|
||||
FFmpeg *ff_new(void);
|
||||
|
||||
void ff_free(FFmpeg *ff);
|
||||
|
||||
int ff_file_open(FFmpeg *ff, const char *file);
|
||||
|
||||
void ff_file_close(FFmpeg *ff);
|
||||
|
||||
void ff_size_get(FFmpeg *ff, int *width, int *height);
|
||||
|
||||
double ff_len_get(FFmpeg *ff);
|
||||
|
||||
int _ff_fps_get(FFmpeg *ff, int *n, int *d);
|
||||
|
||||
int ff_fps_num_get(FFmpeg *ff);
|
||||
|
||||
int ff_fps_den_get(FFmpeg *ff);
|
||||
|
||||
double ff_fps_get(FFmpeg *ff);
|
||||
|
||||
int ff_video_handled(FFmpeg *ff);
|
||||
|
||||
int ff_audio_handled(FFmpeg *ff);
|
||||
|
||||
int ff_format_get(FFmpeg *ff);
|
||||
|
||||
int ff_video_channel_count(FFmpeg *ff);
|
||||
|
||||
void ff_video_channel_set(FFmpeg *ff, int channel);
|
||||
|
||||
int ff_video_channel_get(FFmpeg *ff);
|
||||
|
||||
int ff_audio_channel_count(FFmpeg *ff);
|
||||
|
||||
void ff_audio_channel_set(FFmpeg *ff, int channel);
|
||||
|
||||
int ff_audio_channel_get(FFmpeg *ff);
|
||||
|
||||
#endif /* FFMPEG_H */
|
|
@ -0,0 +1,299 @@
|
|||
/* gcc -g -Wall -Wextra -o ffmpeg main.c ffmpeg.c `pkg-config --cflags --libs ecore-evas libavcodec libavformat libavutil libswscale ecore-evas` */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Ecore.h>
|
||||
#include <Ecore_Evas.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Evas_Object *img;
|
||||
FFmpeg *ff;
|
||||
AVFrame *frame;
|
||||
AVPacket *packet;
|
||||
struct SwsContext *swscale_ctx;
|
||||
int current_frame;
|
||||
} FF_Ctx;
|
||||
|
||||
|
||||
void _quit(Ecore_Evas *ee)
|
||||
{
|
||||
ecore_main_loop_quit();
|
||||
(void)ee;
|
||||
}
|
||||
|
||||
void _resize(Ecore_Evas *ee)
|
||||
{
|
||||
printf("resize\n");
|
||||
(void)ee;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
display_frame_cb(void *data)
|
||||
{
|
||||
FF_Ctx *ff_ctx = data;
|
||||
FF_Video *v;
|
||||
|
||||
ff_ctx->current_frame++;
|
||||
printf("NEW : %d\n", ff_ctx->current_frame);
|
||||
|
||||
while (av_read_frame(ff_ctx->ff->format_ctx, ff_ctx->packet) >= 0)
|
||||
{
|
||||
v = eina_array_data_get(ff_ctx->ff->videos, ff_ctx->ff->video_index);
|
||||
if (ff_ctx->packet->stream_index == v->stream_index)
|
||||
{
|
||||
int response;
|
||||
|
||||
response = avcodec_send_packet(ff_ctx->ff->codec_ctx, ff_ctx->packet);
|
||||
if (response < 0)
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
while (response >= 0)
|
||||
{
|
||||
response = avcodec_receive_frame(ff_ctx->ff->codec_ctx, ff_ctx->frame);
|
||||
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (response < 0) {
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
if (response >= 0)
|
||||
{
|
||||
printf("fame %d: size %d x %d ptr %p %p %p stride: %d %d %d\n",
|
||||
ff_ctx->ff->codec_ctx->frame_number,
|
||||
ff_ctx->frame->width,
|
||||
ff_ctx->frame->height,
|
||||
ff_ctx->frame->data[0],
|
||||
ff_ctx->frame->data[1],
|
||||
ff_ctx->frame->data[2],
|
||||
ff_ctx->frame->linesize[0],
|
||||
ff_ctx->frame->linesize[1],
|
||||
ff_ctx->frame->linesize[2]);
|
||||
evas_object_image_size_set(ff_ctx->img, ff_ctx->frame->width, ff_ctx->frame->height);
|
||||
evas_object_resize(ff_ctx->img, ff_ctx->frame->width, ff_ctx->frame->height);
|
||||
if (ff_ctx->frame->format != AV_PIX_FMT_YUV420P)
|
||||
{
|
||||
printf("NOOOOOO !");
|
||||
}
|
||||
else
|
||||
{
|
||||
evas_object_image_alpha_set(ff_ctx->img, 0);
|
||||
evas_object_image_colorspace_set(ff_ctx->img, EVAS_COLORSPACE_YCBCR422P601_PL);
|
||||
evas_object_image_size_set(ff_ctx->img, ff_ctx->frame->width, ff_ctx->frame->height);
|
||||
evas_object_resize(ff_ctx->img, ff_ctx->frame->width, ff_ctx->frame->height);
|
||||
unsigned char *iter_src;
|
||||
unsigned char **data;
|
||||
unsigned char **iter_dst;
|
||||
int i;
|
||||
|
||||
data = evas_object_image_data_get(ff_ctx->img, 1);
|
||||
if (!data)
|
||||
printf("arg NO NO\n");
|
||||
iter_src = ff_ctx->frame->data[0];
|
||||
iter_dst = data;
|
||||
for (i = 0; i < ff_ctx->frame->height; i++)
|
||||
{
|
||||
printf(" i == %d\n", i);
|
||||
*iter_dst = NULL;
|
||||
*iter_dst = iter_src;
|
||||
iter_dst++;
|
||||
iter_src += ff_ctx->frame->linesize[0];
|
||||
printf(" **** %d\n", (int)(iter_src - ff_ctx->frame->data[0]));
|
||||
}
|
||||
|
||||
iter_src = ff_ctx->frame->data[1];
|
||||
for (i = 0; i < ff_ctx->frame->height / 2; i++)
|
||||
{
|
||||
*iter_dst = iter_src;
|
||||
iter_dst++;
|
||||
iter_src += ff_ctx->frame->linesize[1];
|
||||
}
|
||||
|
||||
iter_src = ff_ctx->frame->data[2];
|
||||
for (i = 0; i < ff_ctx->frame->height / 2; i++)
|
||||
{
|
||||
*iter_dst = iter_src;
|
||||
iter_dst++;
|
||||
iter_src += ff_ctx->frame->linesize[2];
|
||||
}
|
||||
/* unsigned char *out_data[8] = { data, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; */
|
||||
/* int out_line[8] = { ff_ctx->frame->width * 4, 0, 0, 0, 0, 0, 0, 0 }; */
|
||||
/* sws_scale(ff_ctx->swscale_ctx, */
|
||||
/* (const uint8_t * const *)ff_ctx->frame->data, */
|
||||
/* (const int *)ff_ctx->frame->linesize, */
|
||||
/* 0, ff_ctx->frame->height, */
|
||||
/* out_data, out_line); */
|
||||
//unsigned char data = evas_object_image_data_set(ff_ctx->img, ff_ctx->frame->data[0]);
|
||||
evas_object_image_data_set(ff_ctx->img, data);
|
||||
evas_object_image_data_update_add(ff_ctx->img,
|
||||
0, 0,
|
||||
ff_ctx->frame->width,
|
||||
ff_ctx->frame->height);
|
||||
evas_object_image_pixels_dirty_set(ff_ctx->img, 0);
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (av_read_frame(ff_ctx->ff->format_ctx, ff_ctx->packet) >= 0)
|
||||
{
|
||||
v = eina_array_data_get(ff_ctx->ff->videos, ff_ctx->ff->video_index);
|
||||
printf(" stream index : %d %d %d\n",
|
||||
ff_ctx->packet->stream_index,
|
||||
ff_ctx->ff->video_index,
|
||||
v->stream_index);
|
||||
if (ff_ctx->packet->stream_index == v->stream_index)
|
||||
{
|
||||
int response;
|
||||
|
||||
printf("AVPacket->pts %lld\n",
|
||||
ff_ctx->packet->pts);
|
||||
|
||||
response = avcodec_send_packet(ff_ctx->ff->codec_ctx, ff_ctx->packet);
|
||||
if (response < 0)
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
while (response >= 0)
|
||||
{
|
||||
response = avcodec_receive_frame(ff_ctx->ff->codec_ctx, ff_ctx->frame);
|
||||
if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (response < 0) {
|
||||
return response;
|
||||
}
|
||||
|
||||
if (response >= 0)
|
||||
{
|
||||
printf("fame %d: size %d x %d\n",
|
||||
ff_ctx->ff->codec_ctx->frame_number,
|
||||
ff_ctx->frame->width,
|
||||
ff_ctx->frame->height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
void
|
||||
print_info(FFmpeg *ff, int w, int h)
|
||||
{
|
||||
int num, den;
|
||||
printf(" * video size: %d %d\n", w, h);
|
||||
printf(" * duration : %f s\n", ff_len_get(ff));
|
||||
_ff_fps_get(ff, &num, &den);
|
||||
printf(" * video fps : %d %d %.2f %.2f\n", num, den, ff_fps_get(ff), 1.0 / ff_fps_get(ff));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FFmpeg *ff;
|
||||
int res;
|
||||
|
||||
Ecore_Animator *anim;
|
||||
Ecore_Evas *ee;
|
||||
Evas *evas;
|
||||
Evas_Object *o;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("Usage: %s file\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ecore_evas_init();
|
||||
|
||||
ee = ecore_evas_new("software_gdi", 1, 1, 0, 0, NULL);
|
||||
if (!ee)
|
||||
{
|
||||
ecore_evas_shutdown();
|
||||
return 1;
|
||||
}
|
||||
ecore_evas_callback_delete_request_set(ee, _quit);
|
||||
ecore_evas_callback_resize_set(ee, _resize);
|
||||
|
||||
evas = ecore_evas_get(ee);
|
||||
|
||||
o = evas_object_image_filled_add(evas);
|
||||
evas_object_move(o, 0, 0);
|
||||
evas_object_show(o);
|
||||
|
||||
ff = ff_new();
|
||||
if (!ff)
|
||||
{
|
||||
printf("can not create ff\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
res= ff_file_open(ff, argv[1]);
|
||||
if (!res)
|
||||
{
|
||||
printf("can not open file%s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
ff_size_get(ff, &w, &h);
|
||||
print_info(ff, w, h);
|
||||
|
||||
FF_Ctx ff_ctx;
|
||||
|
||||
ff_ctx.current_frame = 0;
|
||||
ff_ctx.img = o;
|
||||
ff_ctx.ff = ff;
|
||||
ff_ctx.frame = av_frame_alloc();
|
||||
if (!ff_ctx.frame)
|
||||
{
|
||||
printf("av_frame_alloc() failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ff_ctx.packet = av_packet_alloc();
|
||||
if (!ff_ctx.packet)
|
||||
{
|
||||
printf("av_packet_alloc() failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ff_ctx.swscale_ctx = sws_getContext(w, h, AV_PIX_FMT_YUV420P,
|
||||
w, h, AV_PIX_FMT_RGB32,
|
||||
SWS_BILINEAR, NULL, NULL, NULL);
|
||||
if (!ff_ctx.swscale_ctx)
|
||||
{
|
||||
printf("sws_alloc_context() failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecore_animator_frametime_set(1.0 / ff_fps_get(ff));
|
||||
anim = ecore_animator_add(display_frame_cb, &ff_ctx);
|
||||
if (!anim)
|
||||
{
|
||||
printf("no anim\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecore_evas_resize(ee, w, h);
|
||||
ecore_evas_show(ee);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
ff_file_close(ff);
|
||||
ff_free(ff);
|
||||
|
||||
ecore_evas_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue