From b26f27d9e3fd44ec5775accdc3666a339684be4c Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Mon, 1 Aug 2022 20:03:12 -0400 Subject: large changes to bitmap structure --- video.cpp | 323 -------------------------------------------------------------- 1 file changed, 323 deletions(-) delete mode 100644 video.cpp (limited to 'video.cpp') diff --git a/video.cpp b/video.cpp deleted file mode 100644 index bb3e17e..0000000 --- a/video.cpp +++ /dev/null @@ -1,323 +0,0 @@ -// workaround to make libav error printing work - -#ifdef av_err2str -#undef av_err2str -#include -av_always_inline std::string av_err2string(int errnum) { - char str[AV_ERROR_MAX_STRING_SIZE]; - return av_make_error_string(str, AV_ERROR_MAX_STRING_SIZE, errnum); -} -#define av_err2str(err) av_err2string(err).c_str() -#endif // av_err2str - -internal bool32 -AV_TryFrame(av_info *AV, int32 *err) -{ - *err = av_read_frame(AV->FileFormatContext, AV->VideoPacket); - if (*err >= 0 && AV->VideoPacket->stream_index != AV->StreamIndex) { - av_packet_unref(AV->VideoPacket); - return 0; - } - - if (*err < 0) - *err = avcodec_send_packet(AV->VideoCodecContext, AV->VideoPacket); - else { - *err = avcodec_send_packet(AV->VideoCodecContext, AV->VideoPacket); - } - av_packet_unref(AV->VideoPacket); - - if (*err < 0) - { - fprintf(stderr, "Libav *error: (%s)\n", av_err2str(*err)); - Assert(0); - } - - while (*err >= 0) { - *err = avcodec_receive_frame(AV->VideoCodecContext, AV->VideoFrame); - if (*err == AVERROR_EOF) { - } else if (*err == AVERROR(EAGAIN)) { - *err = 0; - break; - } else if (*err < 0) { - Assert(0); - } - return 1; - } - return 0; -} - -internal bool32 -TestAV(char *filename) -{ - int32 err = 0; - - // enum AVHWDeviceType type; - // while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) - // printf("%s\n", av_hwdevice_get_type_name(type)); - - AVFormatContext *temp = avformat_alloc_context(); - err = avformat_open_input(&temp, filename, NULL, NULL);; - - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - avformat_free_context(temp); - return 0; - } - - err = avformat_find_stream_info(temp, NULL); - - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - avformat_free_context(temp); - return 0; - } - - avformat_free_context(temp); - - return 1; -} - -internal void -InitAV(char *filename, av_info *AV) -{ - int32 err = 0; - - // enum AVHWDeviceType type; - // while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE) - // printf("%s\n", av_hwdevice_get_type_name(type)); - - AV->FileFormatContext = avformat_alloc_context(); - err = avformat_open_input(&AV->FileFormatContext, filename, NULL, NULL);; - - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - - err = avformat_find_stream_info(AV->FileFormatContext, NULL); - - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - - for (int i = 0; i < AV->FileFormatContext->nb_streams; i++) - { - AVCodecParameters *LocalCodecParameters = NULL; - LocalCodecParameters = AV->FileFormatContext->streams[i]->codecpar; - if (LocalCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) { - AV->VideoCodecParameters = LocalCodecParameters; - AV->VideoStream = AV->FileFormatContext->streams[i]; - AV->StreamIndex = i; - break; - } - } - - if (!AV->VideoCodecParameters) { - printf("Libav error: No video track found."); - } - - AV->VideoCodec = avcodec_find_decoder(AV->VideoCodecParameters->codec_id); - - if (!AV->VideoCodec) { - printf("Libav error: Video codec could not be identified."); - } -/* - int16 codecs = 0; - for (;;) { - AV->VideoHWConfig = avcodec_get_hw_config(AV->VideoCodec, codecs); - if (!AV->VideoHWConfig) { - printf("Libav error: Hardware acceleration not found for decoder %s.", - AV->VideoCodec->name); - break; - } - AV->HWPixFormat = AV->VideoHWConfig->pix_fmt; - break; - // if (AV->VideoHWConfig->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX && - // AV->VideoHWConfig->device_type == type) { - // } - codecs++; - } -*/ - AV->VideoCodecContext = avcodec_alloc_context3(AV->VideoCodec); - if (!AV->VideoCodecContext) { - printf("Libav error: Decoder context allocation failed."); - } - err = avcodec_parameters_to_context(AV->VideoCodecContext, AV->VideoCodecParameters); - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - - avcodec_open2(AV->VideoCodecContext, AV->VideoCodec, NULL); - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - - AV->VideoPacket = av_packet_alloc(); - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - AV->VideoFrame = av_frame_alloc(); - if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - - AV->FPS = (real32)AV->VideoStream->r_frame_rate.num / AV->VideoStream->r_frame_rate.den; - AV->IntFPS = (int32)(AV->FPS + 0.5f); - AV->LastPTS = -1; - - - // TODO(fox): This PTS average isn't exact and causes an occasional - // frame skip. See libav remarks in forum for more details. - - // TODO(fox): Handle footage under five seconds. - int16 TestAmount = 5; - - int16 i = 0; - for (;;) { - if (AV_TryFrame(AV, &err)) { - if (i >= AV->FPS * TestAmount) { - AV->AvgPTSPerSecond = (real32)AV->VideoFrame->pts / TestAmount; - printf("frame: %i, pts: %li\n", i, AV->VideoFrame->pts); - break; - } - i++; - av_frame_unref(AV->VideoFrame); - } - } - - AV->AvgPTSPerFrame = (real32)AV->AvgPTSPerSecond / AV->IntFPS; - printf("Avg PTS per sec: %.06f, Avg PTS per frame: %.06f\n", AV->AvgPTSPerSecond, AV->AvgPTSPerFrame); - - av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD); -}; - -internal void -Convert4x4Chunk(pixel_buffer *Raster, uint8); -internal void -ClearBuffer(pixel_buffer *Raster, void *); - -internal int16 -LoadVideoFrame(video_source *Source, memory *Memory, int32 TimelineFrame) -{ - av_info *AV = &Source->AV; - pixel_buffer *Buffer = &Source->Raster; - int32 *CurrentlyRenderedFrame = &Source->VideoCurrentFrame; - - int32 err = 0; - - int p = 0; - int i = 0; - - int32 FrameToSeek = TimelineFrame - Source->VideoFrameOffset; - if (*CurrentlyRenderedFrame == FrameToSeek || FrameToSeek < 0) - return 0; - - // NOTE(fox): The decoder automatically advances to the next frame, so we - // don't need to call av_seek_frame under normal playback. - // This function only seeks to the nearest "keyframe." - - if (*CurrentlyRenderedFrame != FrameToSeek - 1) { - int64 SeekSeconds = (int64)(FrameToSeek / AV->IntFPS * AV_TIME_BASE); - av_seek_frame(AV->FileFormatContext, -1, SeekSeconds, AVSEEK_FLAG_BACKWARD); - printf("Seek activated\n"); - } else if (*CurrentlyRenderedFrame < 0) { - av_seek_frame(AV->FileFormatContext, -1, 0, AVSEEK_FLAG_BACKWARD); - } - - *CurrentlyRenderedFrame = FrameToSeek; - - int64 SeekPTS = (int64)(AV->AvgPTSPerFrame*FrameToSeek + 0.5f); - - while (err >= 0) { - if (AV_TryFrame(AV, &err)) { - - // The first frame that gets loaded isn't always the actual - // first frame, so we need to check until it's correct. - if (FrameToSeek == 0 && AV->VideoFrame->pts != AV->VideoStream->start_time) { - av_frame_unref(AV->VideoFrame); - printf("NON-START: avg: %li, real pts: %li", SeekPTS, AV->VideoFrame->pts); - continue; - } - - int64 Difference = AV->VideoFrame->pts - SeekPTS; - if (abs(Difference) < AV->AvgPTSPerFrame) - { - if (AV->LastPTS == -1) { - AV->LastPTS = AV->VideoFrame->pts; - printf("avg: %li, real pts: %li, difference: %li\n", SeekPTS, AV->VideoFrame->pts, Difference); - } else { - printf("avg: %li, real pts: %li, difference: %li difference from last pts: %li\n", SeekPTS, AV->VideoFrame->pts, AV->VideoFrame->pts - SeekPTS, AV->VideoFrame->pts - AV->LastPTS); - AV->LastPTS = AV->VideoFrame->pts; - } - - uint32 PixelCount = AV->VideoFrame->width*AV->VideoFrame->height; - int out_linesize[4] = { Buffer->Pitch, Buffer->Pitch, Buffer->Pitch, Buffer->Pitch }; - uint8 *dst_data[4] = { (uint8 *)Buffer->OriginalBuffer, (uint8 *)Buffer->OriginalBuffer + PixelCount, - (uint8 *)Buffer->OriginalBuffer + PixelCount*2, (uint8 *)Buffer->OriginalBuffer + PixelCount*3 }; - - // NOTE(fox): This function will be replaced in the future. - AV->RGBContext = sws_getContext(AV->VideoFrame->width, AV->VideoFrame->height, (AVPixelFormat)AV->VideoFrame->format, - AV->VideoFrame->width, AV->VideoFrame->height, AV_PIX_FMT_RGBA, SWS_BILINEAR, - NULL, NULL, NULL); - - if(!AV->RGBContext) { - printf("Libav error: SwsContext creation failed."); - } - - sws_scale(AV->RGBContext, AV->VideoFrame->data, AV->VideoFrame->linesize, 0, AV->VideoFrame->height, - dst_data, out_linesize); - - av_frame_unref(AV->VideoFrame); - - Convert4x4Chunk(Buffer, 0); - CopyToBuffer(Buffer, 1); - ClearBuffer(Buffer, Buffer->EffectBuffer); - - return 0; - } - else - { - // If this gets printed when not seeking, a frame has been skipped! - printf("FRAME SKIP: avg: %li, real pts: %li, difference: %li\n", SeekPTS, AV->VideoFrame->pts, Difference); - } - av_frame_unref(AV->VideoFrame); - } - } - /* - for (int p = 0; p < 8000; p++) { - av_packet_unref(AV->VideoPacket); - int i = 0; - while (i < 5) - { - err = avcodec_send_packet(AV->VideoCodecContext, AV->VideoPacket); - if (err < 0) - { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - Assert(0); - } - err = avcodec_receive_frame(AV->VideoCodecContext, AV->VideoFrame); - if (err >= 0) { - break; - } else if (err < 0) { - fprintf(stderr, "Libav error: (%s)\n", av_err2str(err)); - } - i++; - } - } - */ - - - /* - uint8 *Test = pFrame->data[0]; - - for (int16 Y = 0; Y < Buffer.Height; Y++) { - for (int16 X = 0; X < Buffer.Width; X++) { - uint8 *Row = (uint8 *)Buffer.OriginalBuffer + Buffer.Pitch*Y; - uint32 *Pixel = (uint32 *)Row + X; - *Pixel = (uint32)((0xFF << 24) | *Test); - Test++; - } - } - */ - - return 0; -} -- cgit v1.2.3