12 # undef AVIIF_KEYFRAME
18 fcc = mmioFOURCC('N', 'o', 'n', 'e'); \
20 if (fcc == BI_RLE8) { \
21 fcc = mmioFOURCC('R', 'l', 'e', '8'); \
33 #include <sys/types.h>
66 # include <libavcodec/avcodec.h>
67 # include <libavformat/avformat.h>
68 # include <libavutil/imgutils.h>
69 # include <libavutil/rational.h>
70 # include <libswscale/swscale.h>
95 # define PATHSEPARATOR '\\'
97 # define PATHSEPARATOR '/'
100 static int an_stringdec(
const char *
string,
char *head,
char *tail,
unsigned short *numlen)
102 unsigned short len, nume, nums = 0;
106 len = strlen(
string);
109 for (i =
len - 1; i >= 0; i--) {
113 if (isdigit(
string[i])) {
130 strcpy(tail, &
string[nume + 1]);
131 strcpy(head,
string);
133 *numlen = nume - nums + 1;
134 return ((
int)atoi(&(
string[nums])));
137 strcpy(head,
string);
143 char *
string,
const char *head,
const char *tail,
unsigned short numlen,
int pic)
149 static void free_anim_avi(
struct anim *
anim)
169 AVIStreamGetFrameClose(
anim->pgf);
173 for (i = 0; i <
anim->avistreams; i++) {
174 AVIStreamRelease(
anim->pavi[i]);
176 anim->avistreams = 0;
178 if (
anim->pfileopen) {
179 AVIFileRelease(
anim->pfile);
190 static void free_anim_ffmpeg(
struct anim *
anim);
196 printf(
"free anim, anim == NULL\n");
207 free_anim_ffmpeg(
anim);
238 AVDictionaryEntry *entry =
NULL;
241 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"METADATA FETCH\n");
244 entry = av_dict_get(
anim->pFormatCtx->
metadata,
"", entry, AV_DICT_IGNORE_SUFFIX);
297 #if !(defined(WITH_AVI) || defined(WITH_FFMPEG))
320 static int startavi(
struct anim *
anim)
326 int i, firstvideo = -1;
330 LPBITMAPINFOHEADER lpbi;
339 printf(
"Can't open avi: %s\n",
anim->
name);
352 if (AVIFileGetStream(
anim->pfile, &
anim->pavi[i], 0
L, i) != AVIERR_OK) {
356 AVIStreamInfo(
anim->pavi[i], &avis,
sizeof(avis));
357 if ((avis.fccType == streamtypeVIDEO) && (firstvideo == -1)) {
358 if (streamcount > 0) {
370 l =
sizeof(abFormat);
371 AVIStreamReadFormat(
anim->pavi[i], 0, &abFormat, &
l);
372 lpbi = (LPBITMAPINFOHEADER)abFormat;
377 FIXCC(avis.fccHandler);
379 printf(
"Can't find AVI decoder for type : %4.4hs/%4.4hs\n",
380 (LPSTR)&avis.fccType,
381 (LPSTR)&avis.fccHandler);
387 anim->avistreams = i;
392 if ((
anim->avistreams == 0) || (firstvideo == -1)) {
397 anim->firstvideo = firstvideo;
408 printf(
"Error loading avi: %s\n",
anim->
name);
426 printf(
"x:%d y:%d size:%d interlace:%d dur:%d\n",
450 if (
anim->avistreams) {
451 LPBITMAPINFOHEADER lpbi;
454 lpbi = AVIStreamGetFrame(
anim->pgf, position + AVIStreamStart(
anim->pavi[
anim->firstvideo]));
471 printf(
"Error reading frame from AVI: '%s'\n",
anim->
name);
491 static int startffmpeg(
struct anim *
anim)
493 int i, video_stream_index;
495 const AVCodec *pCodec;
496 AVFormatContext *pFormatCtx =
NULL;
497 AVCodecContext *pCodecCtx;
498 AVRational frame_rate;
499 AVStream *video_stream;
505 int srcRange, dstRange, brightness, contrast,
saturation;
507 const int *inv_table;
519 if (avformat_find_stream_info(pFormatCtx,
NULL) < 0) {
520 avformat_close_input(&pFormatCtx);
524 av_dump_format(pFormatCtx, 0,
anim->
name, 0);
527 video_stream_index = -1;
529 for (i = 0; i < pFormatCtx->nb_streams; i++) {
530 if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
531 if (streamcount > 0) {
535 video_stream_index = i;
540 if (video_stream_index == -1) {
541 avformat_close_input(&pFormatCtx);
545 video_stream = pFormatCtx->streams[video_stream_index];
548 pCodec = avcodec_find_decoder(video_stream->codecpar->codec_id);
549 if (pCodec ==
NULL) {
550 avformat_close_input(&pFormatCtx);
554 pCodecCtx = avcodec_alloc_context3(
NULL);
555 avcodec_parameters_to_context(pCodecCtx, video_stream->codecpar);
556 pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
558 if (pCodec->capabilities & AV_CODEC_CAP_OTHER_THREADS) {
559 pCodecCtx->thread_count = 0;
565 if (pCodec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
566 pCodecCtx->thread_type = FF_THREAD_FRAME;
568 else if (pCodec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
569 pCodecCtx->thread_type = FF_THREAD_SLICE;
572 if (avcodec_open2(pCodecCtx, pCodec,
NULL) < 0) {
573 avformat_close_input(&pFormatCtx);
576 if (pCodecCtx->pix_fmt == AV_PIX_FMT_NONE) {
577 avcodec_free_context(&
anim->pCodecCtx);
578 avformat_close_input(&pFormatCtx);
582 double video_start = 0;
583 double pts_time_base = av_q2d(video_stream->time_base);
585 if (video_stream->start_time != AV_NOPTS_VALUE) {
586 video_start = video_stream->start_time * pts_time_base;
589 frame_rate = av_guess_frame_rate(pFormatCtx, video_stream,
NULL);
593 if (video_stream->nb_frames != 0) {
598 if (frame_rate.den != 0 && pFormatCtx->duration > 0) {
600 double container_sec = pFormatCtx->duration / (
double)AV_TIME_BASE;
601 if (stream_sec > 4.0 * container_sec) {
614 if (video_stream->duration != AV_NOPTS_VALUE) {
615 stream_dur = video_stream->duration * pts_time_base;
618 double audio_start = 0;
625 for (i = 0; i < pFormatCtx->nb_streams; i++) {
626 if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
627 AVStream *audio_stream = pFormatCtx->streams[i];
628 if (audio_stream->start_time != AV_NOPTS_VALUE) {
629 audio_start = audio_stream->start_time * av_q2d(audio_stream->time_base);
635 if (video_start > audio_start) {
636 stream_dur = (
double)pFormatCtx->duration / AV_TIME_BASE - (video_start - audio_start);
642 stream_dur = (
double)pFormatCtx->duration / AV_TIME_BASE;
648 frs_num = frame_rate.num;
649 frs_den = frame_rate.den;
651 frs_den *= AV_TIME_BASE;
653 while (frs_num % 10 == 0 && frs_den >= 2.0 && frs_num > 10) {
666 anim->
x = pCodecCtx->width;
667 anim->
y = pCodecCtx->height;
669 anim->pFormatCtx = pFormatCtx;
670 anim->pCodecCtx = pCodecCtx;
671 anim->pCodec = pCodec;
672 anim->videoStream = video_stream_index;
679 anim->cur_frame_final = 0;
681 anim->cur_key_frame_pts = -1;
682 anim->cur_packet = av_packet_alloc();
683 anim->cur_packet->stream_index = -1;
685 anim->pFrame = av_frame_alloc();
686 anim->pFrame_backup = av_frame_alloc();
687 anim->pFrame_backup_complete =
false;
688 anim->pFrame_complete =
false;
689 anim->pFrameDeinterlaced = av_frame_alloc();
690 anim->pFrameRGB = av_frame_alloc();
691 anim->pFrameRGB->format = AV_PIX_FMT_RGBA;
695 if (av_frame_get_buffer(
anim->pFrameRGB, 0) < 0) {
696 fprintf(stderr,
"Could not allocate frame data.\n");
697 avcodec_free_context(&
anim->pCodecCtx);
698 avformat_close_input(&
anim->pFormatCtx);
699 av_packet_free(&
anim->cur_packet);
700 av_frame_free(&
anim->pFrameRGB);
701 av_frame_free(&
anim->pFrameDeinterlaced);
702 av_frame_free(&
anim->pFrame);
703 av_frame_free(&
anim->pFrame_backup);
709 fprintf(stderr,
"ffmpeg has changed alloc scheme ... ARGHHH!\n");
710 avcodec_free_context(&
anim->pCodecCtx);
711 avformat_close_input(&
anim->pFormatCtx);
712 av_packet_free(&
anim->cur_packet);
713 av_frame_free(&
anim->pFrameRGB);
714 av_frame_free(&
anim->pFrameDeinterlaced);
715 av_frame_free(&
anim->pFrame);
716 av_frame_free(&
anim->pFrame_backup);
722 av_image_fill_arrays(
anim->pFrameDeinterlaced->data,
723 anim->pFrameDeinterlaced->linesize,
725 anim->pCodecCtx->width,
726 anim->pCodecCtx->height,
728 "ffmpeg deinterlace"),
729 anim->pCodecCtx->pix_fmt,
730 anim->pCodecCtx->width,
731 anim->pCodecCtx->height,
735 anim->img_convert_ctx = sws_getContext(
anim->
x,
737 anim->pCodecCtx->pix_fmt,
741 SWS_BILINEAR | SWS_PRINT_INFO | SWS_FULL_CHR_H_INT,
746 if (!
anim->img_convert_ctx) {
747 fprintf(stderr,
"Can't transform color space??? Bailing out...\n");
748 avcodec_free_context(&
anim->pCodecCtx);
749 avformat_close_input(&
anim->pFormatCtx);
750 av_packet_free(&
anim->cur_packet);
751 av_frame_free(&
anim->pFrameRGB);
752 av_frame_free(&
anim->pFrameDeinterlaced);
753 av_frame_free(&
anim->pFrame);
754 av_frame_free(&
anim->pFrame_backup);
760 if (!sws_getColorspaceDetails(
anim->img_convert_ctx,
768 srcRange = srcRange ||
anim->pCodecCtx->color_range == AVCOL_RANGE_JPEG;
771 if (sws_setColorspaceDetails(
anim->img_convert_ctx,
779 fprintf(stderr,
"Warning: Could not set libswscale colorspace details.\n");
783 fprintf(stderr,
"Warning: Could not set libswscale colorspace details.\n");
789 static double ffmpeg_steps_per_frame_get(
struct anim *
anim)
791 AVStream *v_st =
anim->pFormatCtx->streams[
anim->videoStream];
792 AVRational time_base = v_st->time_base;
793 AVRational frame_rate = av_guess_frame_rate(
anim->pFormatCtx, v_st,
NULL);
794 return av_q2d(av_inv_q(av_mul_q(frame_rate, time_base)));
802 static void ffmpeg_double_buffer_backup_frame_store(
struct anim *
anim,
int64_t pts_to_search)
805 if (
anim->pFrame_backup_complete &&
anim->cur_pts >= pts_to_search) {
808 if (!
anim->pFrame_complete) {
812 if (
anim->pFrame_backup_complete) {
813 av_frame_unref(
anim->pFrame_backup);
816 av_frame_move_ref(
anim->pFrame_backup,
anim->pFrame);
817 anim->pFrame_backup_complete =
true;
821 static void ffmpeg_double_buffer_backup_frame_clear(
struct anim *
anim)
823 if (
anim->pFrame_backup_complete) {
824 av_frame_unref(
anim->pFrame_backup);
826 anim->pFrame_backup_complete =
false;
830 static AVFrame *ffmpeg_double_buffer_frame_fallback_get(
struct anim *
anim)
832 av_log(
anim->pFormatCtx, AV_LOG_ERROR,
"DECODE UNHAPPY: PTS not matched!\n");
834 if (
anim->pFrame_complete) {
837 if (
anim->pFrame_backup_complete) {
838 return anim->pFrame_backup;
849 static void ffmpeg_postprocess(
struct anim *
anim, AVFrame *
input)
859 "data not read properly...\n");
863 av_log(
anim->pFormatCtx,
865 " POSTPROC: AVFrame planes: %p %p %p %p\n",
874 anim->pCodecCtx->pix_fmt,
875 anim->pCodecCtx->width,
876 anim->pCodecCtx->height) < 0) {
884 sws_scale(
anim->img_convert_ctx,
889 anim->pFrameRGB->data,
890 anim->pFrameRGB->linesize);
893 int aligned_stride =
anim->pFrameRGB->linesize[0];
895 anim->pFrameRGB->data[0] + (
anim->
y - 1) * aligned_stride, 0, 0, 0};
899 const int src_linesize[4] = {-
anim->pFrameRGB->linesize[0], 0, 0, 0};
900 int dst_size = av_image_get_buffer_size(
901 anim->pFrameRGB->format,
anim->pFrameRGB->width,
anim->pFrameRGB->height, 1);
902 av_image_copy_to_buffer(
909 static void final_frame_log(
struct anim *
anim,
914 av_log(
anim->pFormatCtx,
916 "DECODE HAPPY: %s frame PTS range %" PRId64 " - %" PRId64 ".\n",
924 return pts_start <= pts_to_search && pts_to_search < pts_end;
928 static AVFrame *ffmpeg_frame_by_pts_get(
struct anim *
anim,
int64_t pts_to_search)
934 if (!
anim->pFrame_complete) {
938 const bool backup_frame_ready =
anim->pFrame_backup_complete;
940 const int64_t recent_end = recent_start +
anim->pFrame->pkt_duration;
943 AVFrame *best_frame =
NULL;
944 if (ffmpeg_pts_isect(recent_start, recent_end, pts_to_search)) {
945 final_frame_log(
anim, recent_start, recent_end,
"Recent");
946 best_frame =
anim->pFrame;
948 else if (backup_frame_ready && ffmpeg_pts_isect(backup_start, recent_start, pts_to_search)) {
949 final_frame_log(
anim, backup_start, recent_start,
"Backup");
950 best_frame =
anim->pFrame_backup;
955 static void ffmpeg_decode_store_frame_pts(
struct anim *
anim)
959 if (
anim->pFrame->key_frame) {
960 anim->cur_key_frame_pts =
anim->cur_pts;
963 av_log(
anim->pFormatCtx,
965 " FRAME DONE: cur_pts=%" PRId64 ", guessed_pts=%" PRId64 "\n",
970 static int ffmpeg_read_video_frame(
struct anim *
anim, AVPacket *packet)
973 while ((
ret = av_read_frame(
anim->pFormatCtx, packet)) >= 0) {
974 if (packet->stream_index ==
anim->videoStream) {
977 av_packet_unref(packet);
978 packet->stream_index = -1;
985 static int ffmpeg_decode_video_frame(
struct anim *
anim)
987 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
" DECODE VIDEO FRAME\n");
991 anim->pFrame_complete = avcodec_receive_frame(
anim->pCodecCtx,
anim->pFrame) == 0;
992 if (
anim->pFrame_complete) {
993 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
" DECODE FROM CODEC BUFFER\n");
994 ffmpeg_decode_store_frame_pts(
anim);
999 if (
anim->cur_packet->stream_index ==
anim->videoStream) {
1000 av_packet_unref(
anim->cur_packet);
1001 anim->cur_packet->stream_index = -1;
1004 while ((rval = ffmpeg_read_video_frame(
anim,
anim->cur_packet)) >= 0) {
1005 if (
anim->cur_packet->stream_index !=
anim->videoStream) {
1009 av_log(
anim->pFormatCtx,
1012 anim->cur_packet->stream_index,
1013 (
anim->cur_packet->dts == AV_NOPTS_VALUE) ? -1 : (
int64_t)
anim->cur_packet->dts,
1014 (
anim->cur_packet->pts == AV_NOPTS_VALUE) ? -1 : (
int64_t)
anim->cur_packet->pts,
1015 (
anim->cur_packet->flags & AV_PKT_FLAG_KEY) ?
" KEY" :
"");
1017 avcodec_send_packet(
anim->pCodecCtx,
anim->cur_packet);
1018 anim->pFrame_complete = avcodec_receive_frame(
anim->pCodecCtx,
anim->pFrame) == 0;
1020 if (
anim->pFrame_complete) {
1021 ffmpeg_decode_store_frame_pts(
anim);
1024 av_packet_unref(
anim->cur_packet);
1025 anim->cur_packet->stream_index = -1;
1028 if (rval == AVERROR_EOF) {
1030 avcodec_send_packet(
anim->pCodecCtx,
NULL);
1031 anim->pFrame_complete = avcodec_receive_frame(
anim->pCodecCtx,
anim->pFrame) == 0;
1033 if (
anim->pFrame_complete) {
1034 ffmpeg_decode_store_frame_pts(
anim);
1040 av_packet_unref(
anim->cur_packet);
1041 anim->cur_packet->stream_index = -1;
1043 av_log(
anim->pFormatCtx,
1045 " DECODE READ FAILED: av_read_frame() "
1046 "returned error: %s\n",
1053 static int match_format(
const char *
name, AVFormatContext *pFormatCtx)
1058 const char *
names = pFormatCtx->iformat->name;
1064 namelen = strlen(
name);
1065 while ((p = strchr(
names,
','))) {
1075 static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
1077 static const char *byte_seek_list[] = {
"mpegts", 0};
1080 if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
1087 if (match_format(*p++, pFormatCtx)) {
1104 int64_t seek_pts = pts_to_search - (ffmpeg_steps_per_frame_get(
anim) * 3);
1126 AVStream *v_st =
anim->pFormatCtx->streams[
anim->videoStream];
1127 int64_t start_pts = v_st->start_time;
1129 pts_to_search = round(position * ffmpeg_steps_per_frame_get(
anim));
1131 if (start_pts != AV_NOPTS_VALUE) {
1132 pts_to_search += start_pts;
1135 return pts_to_search;
1138 static bool ffmpeg_is_first_frame_decode(
struct anim *
anim)
1140 return anim->pFrame_complete ==
false;
1146 int64_t frame_pts_end = frame_pts_start +
anim->pFrame->pkt_duration;
1147 av_log(
anim->pFormatCtx,
1156 static void ffmpeg_decode_video_frame_scan(
struct anim *
anim,
int64_t pts_to_search)
1158 const int64_t start_gop_frame =
anim->cur_key_frame_pts;
1159 bool decode_error =
false;
1161 while (!decode_error &&
anim->cur_pts < pts_to_search) {
1162 ffmpeg_scan_log(
anim, pts_to_search);
1163 ffmpeg_double_buffer_backup_frame_store(
anim, pts_to_search);
1164 decode_error = ffmpeg_decode_video_frame(
anim) < 1;
1170 if (
anim->seek_before_decode && start_gop_frame !=
anim->cur_key_frame_pts) {
1171 av_log(
anim->pFormatCtx, AV_LOG_ERROR,
"SCAN: Frame belongs to an unexpected GOP!\n");
1181 static int ffmpeg_generic_seek_workaround(
struct anim *
anim,
1185 int64_t current_pts = *requested_pts;
1188 int64_t cur_pts, prev_pts = -1;
1191 while (current_pts != 0) {
1192 current_pts = *requested_pts - (
int64_t)round(
offset * ffmpeg_steps_per_frame_get(
anim));
1193 current_pts =
MAX2(current_pts, 0);
1196 if (av_seek_frame(
anim->pFormatCtx,
anim->videoStream, current_pts, AVSEEK_FLAG_BACKWARD) <
1202 AVPacket *read_packet = av_packet_alloc();
1203 while (av_read_frame(
anim->pFormatCtx, read_packet) >= 0) {
1204 if (read_packet->stream_index ==
anim->videoStream) {
1207 av_packet_unref(read_packet);
1211 bool is_key_frame = read_packet->flags & AV_PKT_FLAG_KEY;
1216 av_packet_free(&read_packet);
1219 if (cur_pts <= pts_to_search) {
1225 if (cur_pts == prev_pts) {
1235 *requested_pts = current_pts;
1238 return av_seek_frame(
anim->pFormatCtx,
anim->videoStream, current_pts, AVSEEK_FLAG_BACKWARD);
1243 static void ffmpeg_seek_recover_stream_position(
struct anim *
anim)
1245 AVPacket *temp_packet = av_packet_alloc();
1246 while (ffmpeg_read_video_frame(
anim, temp_packet) >= 0) {
1249 av_packet_unref(temp_packet);
1251 if (current_pts == temp_pts) {
1255 av_packet_free(&temp_packet);
1259 static bool ffmpeg_seek_buffers_need_flushing(
struct anim *
anim,
int position,
int64_t seek_pos)
1262 AVPacket *temp_packet = av_packet_alloc();
1263 ffmpeg_read_video_frame(
anim, temp_packet);
1265 av_packet_unref(temp_packet);
1266 av_packet_free(&temp_packet);
1277 ffmpeg_seek_recover_stream_position(
anim);
1282 av_seek_frame(
anim->pFormatCtx,
anim->videoStream, seek_pos, AVSEEK_FLAG_BACKWARD);
1283 anim->cur_key_frame_pts = gop_pts;
1288 static int ffmpeg_seek_to_key_frame(
struct anim *
anim,
1314 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"TC INDEX seek seek_pos = %" PRId64 "\n", seek_pos);
1315 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"TC INDEX seek pts = %" PRIu64 "\n", pts);
1316 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"TC INDEX seek dts = %" PRIu64 "\n", dts);
1318 if (ffmpeg_seek_by_byte(
anim->pFormatCtx)) {
1319 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"... using BYTE seek_pos\n");
1321 ret = av_seek_frame(
anim->pFormatCtx, -1, seek_pos, AVSEEK_FLAG_BYTE);
1324 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"... using PTS seek_pos\n");
1325 ret = av_seek_frame(
1326 anim->pFormatCtx,
anim->videoStream,
anim->cur_key_frame_pts, AVSEEK_FLAG_BACKWARD);
1332 seek_pos = ffmpeg_get_seek_pts(
anim, pts_to_search);
1334 anim->pFormatCtx, AV_LOG_DEBUG,
"NO INDEX final seek seek_pos = %" PRId64 "\n", seek_pos);
1336 AVFormatContext *format_ctx =
anim->pFormatCtx;
1338 if (format_ctx->iformat->read_seek2 || format_ctx->iformat->read_seek) {
1339 ret = av_seek_frame(
anim->pFormatCtx,
anim->videoStream, seek_pos, AVSEEK_FLAG_BACKWARD);
1342 ret = ffmpeg_generic_seek_workaround(
anim, &seek_pos, pts_to_search);
1343 av_log(
anim->pFormatCtx,
1345 "Adjusted final seek seek_pos = %" PRId64 "\n",
1349 if (
ret <= 0 && !ffmpeg_seek_buffers_need_flushing(
anim, position, seek_pos)) {
1355 av_log(
anim->pFormatCtx,
1358 "error while seeking to DTS = %" PRId64 " (frameno = %d, PTS = %" PRId64
1359 "): errcode = %d\n",
1367 avcodec_flush_buffers(
anim->pCodecCtx);
1368 ffmpeg_double_buffer_backup_frame_clear(
anim);
1372 if (
anim->cur_packet->stream_index ==
anim->videoStream) {
1373 av_packet_unref(
anim->cur_packet);
1374 anim->cur_packet->stream_index = -1;
1380 static bool ffmpeg_must_seek(
struct anim *
anim,
int position)
1383 anim->seek_before_decode = must_seek;
1393 av_log(
anim->pFormatCtx, AV_LOG_DEBUG,
"FETCH: seek_pos=%d\n", position);
1396 int64_t pts_to_search = ffmpeg_get_pts_to_search(
anim, tc_index, position);
1397 AVStream *v_st =
anim->pFormatCtx->streams[
anim->videoStream];
1398 double frame_rate = av_q2d(v_st->r_frame_rate);
1399 double pts_time_base = av_q2d(v_st->time_base);
1400 int64_t start_pts = v_st->start_time;
1402 av_log(
anim->pFormatCtx,
1404 "FETCH: looking for PTS=%" PRId64 " (pts_timebase=%g, frame_rate=%g, start_pts=%" PRId64
1411 if (ffmpeg_must_seek(
anim, position)) {
1412 ffmpeg_seek_to_key_frame(
anim, position, tc_index, pts_to_search);
1415 ffmpeg_decode_video_frame_scan(
anim, pts_to_search);
1438 const AVPixFmtDescriptor *pix_fmt_descriptor = av_pix_fmt_desc_get(
anim->pCodecCtx->pix_fmt);
1441 if ((pix_fmt_descriptor->flags & AV_PIX_FMT_FLAG_ALPHA) == 0) {
1447 (
size_t)4 *
anim->
x *
anim->
y, 32,
"ffmpeg ibuf");
1452 AVFrame *final_frame = ffmpeg_frame_by_pts_get(
anim, pts_to_search);
1453 if (final_frame ==
NULL) {
1456 final_frame = ffmpeg_double_buffer_frame_fallback_get(
anim);
1461 if (final_frame !=
NULL) {
1462 ffmpeg_postprocess(
anim, final_frame);
1469 return anim->cur_frame_final;
1472 static void free_anim_ffmpeg(
struct anim *
anim)
1478 if (
anim->pCodecCtx) {
1479 avcodec_free_context(&
anim->pCodecCtx);
1480 avformat_close_input(&
anim->pFormatCtx);
1481 av_packet_free(&
anim->cur_packet);
1483 av_frame_free(&
anim->pFrame);
1484 av_frame_free(&
anim->pFrame_backup);
1485 av_frame_free(&
anim->pFrameRGB);
1486 av_frame_free(&
anim->pFrameDeinterlaced);
1488 sws_freeContext(
anim->img_convert_ctx);
1511 free_anim_avi(
anim);
1515 free_anim_ffmpeg(
anim);
1540 if (startavi(
anim)) {
1541 printf(
"couldn't start avi\n");
1548 if (startffmpeg(
anim)) {
1577 char head[256], tail[256];
1578 unsigned short digits;
1630 ibuf = avi_fetchibuf(
anim, position);
1638 ibuf = ffmpeg_fetchibuf(
anim, position, tc);
1680 double frs_sec_base_double;
1685 *frs_sec = SHRT_MAX;
1694 *frs_sec_base = (
float)(frs_sec_base_double / AV_TIME_BASE);
1697 *frs_sec_base = (
float)frs_sec_base_double;
1701 *frs_sec_base = (
float)frs_sec_base_double;
AviError AVI_close(AviMovie *movie)
void * AVI_read_frame(AviMovie *movie, AviFormat format, int frame, int stream)
AviError AVI_print_error(AviError error)
int AVI_get_stream(AviMovie *movie, int avist_type, int stream_num)
AviError AVI_open_movie(const char *name, AviMovie *movie)
typedef float(TangentPoint)[2]
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BLI_path_sequence_encode(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
int BLI_strncasecmp(const char *s1, const char *s2, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_strcasecmp(const char *s1, const char *s2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
int BLI_system_thread_count(void)
Compatibility-like things for windows.
typedef double(DMatrix)[4][4]
#define R_IMF_PLANES_RGBA
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
@ COLOR_ROLE_DEFAULT_BYTE
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
void IMB_filtery(struct ImBuf *ibuf)
int IMB_anim_index_get_frame_index(struct anim *anim, IMB_Timecode_Type tc, int position)
void IMB_refImBuf(struct ImBuf *ibuf)
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
struct ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
int imb_get_anim_type(const char *filepath)
Contains defines and structs used throughout the imbuf module.
uint64_t IMB_indexer_get_seek_pos(struct anim_index *idx, int frame_index)
uint64_t IMB_indexer_get_seek_pos_pts(struct anim_index *idx, int frame_index)
struct anim_index * IMB_anim_open_index(struct anim *anim, IMB_Timecode_Type tc)
uint64_t IMB_indexer_get_seek_pos_dts(struct anim_index *idx, int frame_index)
void IMB_free_indices(struct anim *anim)
int IMB_indexer_get_duration(struct anim_index *idx)
struct anim * IMB_anim_open_proxy(struct anim *anim, IMB_Proxy_Size preview_size)
int IMB_indexer_can_scan(struct anim_index *idx, int old_frame_index, int new_frame_index)
uint64_t IMB_indexer_get_pts(struct anim_index *idx, int frame_index)
int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno)
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its saturation
static int an_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
void IMB_close_anim_proxies(struct anim *anim)
bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
void IMB_free_anim(struct anim *anim)
int ismovie(const char *UNUSED(filepath))
void IMB_close_anim(struct anim *anim)
static ImBuf * movie_fetchibuf(struct anim *UNUSED(anim), int UNUSED(position))
static void free_anim_movie(struct anim *UNUSED(anim))
int IMB_anim_get_image_height(struct anim *anim)
static int startmovie(struct anim *UNUSED(anim))
struct anim * IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
static bool anim_getnew(struct anim *anim)
static void an_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
struct IDProperty * IMB_anim_load_metadata(struct anim *anim)
struct ImBuf * IMB_anim_previewframe(struct anim *anim)
void IMB_suffix_anim(struct anim *anim, const char *suffix)
double IMD_anim_get_offset(struct anim *anim)
int IMB_anim_get_image_width(struct anim *anim)
struct ImBuf * IMB_anim_absolute(struct anim *anim, int position, IMB_Timecode_Type tc, IMB_Proxy_Size preview_size)
bool IMB_anim_can_produce_frames(const struct anim *anim)
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
void colorspace_set_default_role(char *colorspace, int size, int role)
ColorSpace * colormanage_colorspace_get_named(const char *name)
SyclQueue void void * src
FFMPEG_INLINE int64_t timestamp_from_pts_or_dts(int64_t pts, int64_t dts)
FFMPEG_INLINE int64_t av_get_pts_from_frame(AVFrame *picture)
FFMPEG_INLINE int av_image_deinterlace(AVFrame *dst, const AVFrame *src, enum AVPixelFormat pix_fmt, int width, int height)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ccl_global KernelShaderEvalInput * input
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
void *(* MEM_callocN)(size_t len, const char *str)
unsigned __int64 uint64_t
struct ColorSpace * rect_colorspace
char name[IMB_FILENAME_SIZE]
struct IDProperty * metadata