for now, but it seems to work. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@3627 92316355-f0b4-4df1-b90c-862c8a59935fmaster
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * makemovie read image names from stdin and create a movie | |||
| * Copyright (c) 2009 Sam Hocevar <sam@zoy.org> | |||
| * Copyright (c) 2009 Sam Hocevar <sam@hocevar.net> | |||
| * All Rights Reserved | |||
| * | |||
| * $Id$ | |||
| @@ -18,111 +18,31 @@ | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <libavformat/avformat.h> | |||
| #include <libswscale/swscale.h> | |||
| #include <pipi.h> | |||
| /* These values define a 720x576 anamorphic widescreen image that gets | |||
| * scaled to 1024x576 (16:9). */ | |||
| #define WIDTH 720 | |||
| #define HEIGHT 576 | |||
| #define PAR_NUM 64 | |||
| #define PAR_DEN 45 | |||
| #define FPS 25 | |||
| #define BITRATE 16*1024*1024 | |||
| #define WIDTH 1280 | |||
| #define HEIGHT 720 | |||
| #define FPS 30 | |||
| int main(int argc, char *argv[]) | |||
| { | |||
| char file[1024]; | |||
| AVPacket packet; | |||
| AVFormatContext *fmt; | |||
| AVCodecContext *ctx; | |||
| AVStream *stream; | |||
| AVCodec *codec; | |||
| AVFrame *frame; | |||
| struct SwsContext *sws = NULL; | |||
| pipi_image_t *image; | |||
| pipi_sequence_t *seq; | |||
| pipi_pixels_t *p; | |||
| uint8_t *buffer, *tmp; | |||
| int f, len; | |||
| int f; | |||
| if(argc < 2) | |||
| return EXIT_FAILURE; | |||
| av_register_all(); | |||
| fmt = avformat_alloc_context(); | |||
| if(!fmt) | |||
| return EXIT_FAILURE; | |||
| snprintf(fmt->filename, sizeof(fmt->filename), "%s", argv[1]); | |||
| fmt->oformat = guess_format(NULL, argv[1], NULL); | |||
| if(!fmt->oformat) | |||
| fmt->oformat = guess_format("mpeg", NULL, NULL); | |||
| if(!fmt->oformat) | |||
| return EXIT_FAILURE; | |||
| stream = av_new_stream(fmt, 0); | |||
| if(!stream) | |||
| return EXIT_FAILURE; | |||
| stream->sample_aspect_ratio.num = PAR_NUM; | |||
| stream->sample_aspect_ratio.den = PAR_DEN; | |||
| ctx = stream->codec; | |||
| ctx->width = WIDTH; | |||
| ctx->height = HEIGHT; | |||
| ctx->sample_aspect_ratio.num = PAR_NUM; | |||
| ctx->sample_aspect_ratio.den = PAR_DEN; | |||
| ctx->codec_id = fmt->oformat->video_codec; | |||
| //ctx->codec_id = CODEC_ID_FFV1; | |||
| //ctx->codec_id = CODEC_ID_THEORA; | |||
| //ctx->codec_id = CODEC_ID_SNOW; | |||
| //ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; /* Snow */ | |||
| //ctx->codec_id = CODEC_ID_MJPEG; | |||
| ctx->codec_type = CODEC_TYPE_VIDEO; | |||
| ctx->bit_rate = BITRATE; | |||
| ctx->time_base.num = 1; | |||
| ctx->time_base.den = FPS; /* 25 fps */ | |||
| ctx->gop_size = FPS / 2; | |||
| ctx->pix_fmt = PIX_FMT_YUV420P; /* send YUV 420 */ | |||
| if(ctx->codec_id == CODEC_ID_MPEG2VIDEO) | |||
| ctx->max_b_frames = 2; | |||
| if(ctx->codec_id == CODEC_ID_MPEG1VIDEO) | |||
| ctx->mb_decision = 2; | |||
| if(fmt->oformat->flags & AVFMT_GLOBALHEADER) | |||
| ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |||
| if(av_set_parameters(fmt, NULL) < 0) | |||
| return EXIT_FAILURE; | |||
| codec = avcodec_find_encoder(ctx->codec_id); | |||
| if(!codec) | |||
| return EXIT_FAILURE; | |||
| if(avcodec_open(ctx, codec) < 0) | |||
| return EXIT_FAILURE; | |||
| frame = avcodec_alloc_frame(); | |||
| if(!frame) | |||
| return EXIT_FAILURE; | |||
| tmp = av_malloc(avpicture_get_size(ctx->pix_fmt, ctx->width, ctx->height)); | |||
| if(!tmp) | |||
| seq = pipi_open_sequence(argv[1], WIDTH, HEIGHT, FPS); | |||
| if(!seq) | |||
| return EXIT_FAILURE; | |||
| avpicture_fill((AVPicture *)frame, tmp, ctx->pix_fmt, | |||
| ctx->width, ctx->height); | |||
| if(!(fmt->flags & AVFMT_NOFILE)) | |||
| if(url_fopen(&fmt->pb, argv[1], URL_WRONLY) < 0) | |||
| return EXIT_FAILURE; | |||
| len = 64 * 1024 * 1024; | |||
| buffer = av_malloc(len); | |||
| av_write_header(fmt); | |||
| for(f = 0; ; f++) | |||
| { | |||
| uint8_t *start; | |||
| int w = 0, h = 0, bytes, pitch; | |||
| int w = 0, h = 0; | |||
| if(!fgets(file, sizeof(file), stdin)) | |||
| break; | |||
| @@ -133,61 +53,15 @@ int main(int argc, char *argv[]) | |||
| return EXIT_FAILURE; | |||
| p = pipi_get_pixels(image, PIPI_PIXELS_RGBA_U8); | |||
| start = (uint8_t *)p->pixels; | |||
| pitch = p->w * 4; | |||
| if(w != p->w || h != p->h) | |||
| { | |||
| w = p->w; | |||
| h = p->h; | |||
| if(sws) | |||
| sws_freeContext(sws); | |||
| sws = NULL; | |||
| } | |||
| if(!sws) | |||
| sws = sws_getContext(w, h, PIX_FMT_RGB32, ctx->width, ctx->height, | |||
| ctx->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL); | |||
| sws_scale(sws, &start, &pitch, 0, h, frame->data, frame->linesize); | |||
| pipi_feed_sequence(seq, start, p->w, p->h); | |||
| pipi_free(image); | |||
| bytes = avcodec_encode_video(ctx, buffer, len, frame); | |||
| if(bytes <= 0) | |||
| continue; | |||
| av_init_packet(&packet); | |||
| if(ctx->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) | |||
| packet.pts = av_rescale_q(ctx->coded_frame->pts, | |||
| ctx->time_base, stream->time_base); | |||
| if(ctx->coded_frame->key_frame) | |||
| packet.flags |= PKT_FLAG_KEY; | |||
| packet.stream_index = 0; | |||
| packet.data = buffer; | |||
| packet.size = bytes; | |||
| if(av_interleaved_write_frame(fmt, &packet) < 0) | |||
| return EXIT_FAILURE; | |||
| fprintf(stderr, "frame %d\r", f); | |||
| } | |||
| fprintf(stderr, "\n"); | |||
| av_write_trailer(fmt); | |||
| avcodec_close(stream->codec); | |||
| av_free(frame->data[0]); | |||
| av_free(frame); | |||
| av_free(buffer); | |||
| av_freep(&fmt->streams[0]->codec); | |||
| av_freep(&fmt->streams[0]); | |||
| if(sws) | |||
| sws_freeContext(sws); | |||
| if(!(fmt->flags & AVFMT_NOFILE)) | |||
| url_fclose(fmt->pb); | |||
| av_free(fmt); | |||
| pipi_close_sequence(seq); | |||
| return EXIT_SUCCESS; | |||
| } | |||
| @@ -0,0 +1,192 @@ | |||
| <?xml version="1.0" encoding="Windows-1252"?> | |||
| <VisualStudioProject | |||
| ProjectType="Visual C++" | |||
| Version="9.00" | |||
| Name="makemovie" | |||
| ProjectGUID="{A65DC7CE-D5BF-4CB6-942F-C970076E68C9}" | |||
| RootNamespace="makemovie" | |||
| Keyword="Win32Proj" | |||
| TargetFrameworkVersion="131072" | |||
| > | |||
| <Platforms> | |||
| <Platform | |||
| Name="Win32" | |||
| /> | |||
| </Platforms> | |||
| <ToolFiles> | |||
| </ToolFiles> | |||
| <Configurations> | |||
| <Configuration | |||
| Name="Debug|Win32" | |||
| OutputDirectory="$(SolutionDir)\win32\$(ConfigurationName)\bin" | |||
| IntermediateDirectory="$(OutDir)\$(ProjectName)" | |||
| ConfigurationType="1" | |||
| CharacterSet="1" | |||
| > | |||
| <Tool | |||
| Name="VCPreBuildEventTool" | |||
| CommandLine="" | |||
| /> | |||
| <Tool | |||
| Name="VCCustomBuildTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXMLDataGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCWebServiceProxyGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCMIDLTool" | |||
| /> | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| Optimization="0" | |||
| AdditionalIncludeDirectories="..\win32;..\pipi;..\win32\ffmpeg\include" | |||
| PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" | |||
| MinimalRebuild="true" | |||
| BasicRuntimeChecks="3" | |||
| RuntimeLibrary="3" | |||
| UsePrecompiledHeader="0" | |||
| WarningLevel="3" | |||
| Detect64BitPortabilityProblems="true" | |||
| DebugInformationFormat="4" | |||
| /> | |||
| <Tool | |||
| Name="VCManagedResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPreLinkEventTool" | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| AdditionalDependencies="avutil-50.lib avformat-52.lib avcodec-52.lib swscale-0.lib" | |||
| LinkIncremental="2" | |||
| AdditionalLibraryDirectories="..\win32\ffmpeg\lib" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="1" | |||
| RandomizedBaseAddress="1" | |||
| DataExecutionPrevention="0" | |||
| TargetMachine="1" | |||
| /> | |||
| <Tool | |||
| Name="VCALinkTool" | |||
| /> | |||
| <Tool | |||
| Name="VCManifestTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXDCMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCBscMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCFxCopTool" | |||
| /> | |||
| <Tool | |||
| Name="VCAppVerifierTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| CommandLine="xcopy /Y /D $(SolutionDir)\win32\ffmpeg\lib\*.dll $(OutDir)" | |||
| /> | |||
| </Configuration> | |||
| <Configuration | |||
| Name="Release|Win32" | |||
| OutputDirectory="$(SolutionDir)\win32\$(ConfigurationName)\bin" | |||
| IntermediateDirectory="$(OutDir)\$(ProjectName)" | |||
| ConfigurationType="1" | |||
| CharacterSet="1" | |||
| WholeProgramOptimization="1" | |||
| > | |||
| <Tool | |||
| Name="VCPreBuildEventTool" | |||
| CommandLine="" | |||
| /> | |||
| <Tool | |||
| Name="VCCustomBuildTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXMLDataGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCWebServiceProxyGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCMIDLTool" | |||
| /> | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| AdditionalIncludeDirectories="..\win32;..\pipi;..\win32\ffmpeg\include" | |||
| PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" | |||
| RuntimeLibrary="2" | |||
| UsePrecompiledHeader="0" | |||
| WarningLevel="3" | |||
| Detect64BitPortabilityProblems="true" | |||
| DebugInformationFormat="3" | |||
| /> | |||
| <Tool | |||
| Name="VCManagedResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPreLinkEventTool" | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| AdditionalDependencies="avutil-50.lib avformat-52.lib avcodec-52.lib swscale-0.lib" | |||
| LinkIncremental="2" | |||
| AdditionalLibraryDirectories="..\win32\ffmpeg\lib" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="1" | |||
| OptimizeReferences="2" | |||
| EnableCOMDATFolding="2" | |||
| RandomizedBaseAddress="1" | |||
| DataExecutionPrevention="0" | |||
| TargetMachine="1" | |||
| /> | |||
| <Tool | |||
| Name="VCALinkTool" | |||
| /> | |||
| <Tool | |||
| Name="VCManifestTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXDCMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCBscMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCFxCopTool" | |||
| /> | |||
| <Tool | |||
| Name="VCAppVerifierTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| CommandLine="xcopy /Y /D $(SolutionDir)\win32\ffmpeg\lib\*.dll $(OutDir)" | |||
| /> | |||
| </Configuration> | |||
| </Configurations> | |||
| <References> | |||
| </References> | |||
| <Files> | |||
| <File | |||
| RelativePath="..\win32\config.h" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath=".\makemovie.c" | |||
| > | |||
| </File> | |||
| </Files> | |||
| <Globals> | |||
| </Globals> | |||
| </VisualStudioProject> | |||
| @@ -0,0 +1,186 @@ | |||
| <?xml version="1.0" encoding="Windows-1252"?> | |||
| <VisualStudioProject | |||
| ProjectType="Visual C++" | |||
| Version="9.00" | |||
| Name="sharpen" | |||
| ProjectGUID="{D405CD0E-F47F-4C6E-9CB5-2B0F00E7C6D0}" | |||
| RootNamespace="sharpen" | |||
| Keyword="Win32Proj" | |||
| TargetFrameworkVersion="131072" | |||
| > | |||
| <Platforms> | |||
| <Platform | |||
| Name="Win32" | |||
| /> | |||
| </Platforms> | |||
| <ToolFiles> | |||
| </ToolFiles> | |||
| <Configurations> | |||
| <Configuration | |||
| Name="Debug|Win32" | |||
| OutputDirectory="$(SolutionDir)/win32/$(ConfigurationName)/bin" | |||
| IntermediateDirectory="$(OutDir)/$(ProjectName)" | |||
| ConfigurationType="1" | |||
| CharacterSet="1" | |||
| > | |||
| <Tool | |||
| Name="VCPreBuildEventTool" | |||
| CommandLine="" | |||
| /> | |||
| <Tool | |||
| Name="VCCustomBuildTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXMLDataGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCWebServiceProxyGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCMIDLTool" | |||
| /> | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| Optimization="0" | |||
| AdditionalIncludeDirectories="..\win32;..\pipi" | |||
| PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" | |||
| MinimalRebuild="true" | |||
| BasicRuntimeChecks="3" | |||
| RuntimeLibrary="3" | |||
| UsePrecompiledHeader="0" | |||
| WarningLevel="3" | |||
| Detect64BitPortabilityProblems="true" | |||
| DebugInformationFormat="4" | |||
| /> | |||
| <Tool | |||
| Name="VCManagedResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPreLinkEventTool" | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| LinkIncremental="2" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="1" | |||
| RandomizedBaseAddress="1" | |||
| DataExecutionPrevention="0" | |||
| TargetMachine="1" | |||
| /> | |||
| <Tool | |||
| Name="VCALinkTool" | |||
| /> | |||
| <Tool | |||
| Name="VCManifestTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXDCMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCBscMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCFxCopTool" | |||
| /> | |||
| <Tool | |||
| Name="VCAppVerifierTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| /> | |||
| </Configuration> | |||
| <Configuration | |||
| Name="Release|Win32" | |||
| OutputDirectory="$(SolutionDir)/win32/$(ConfigurationName)/bin" | |||
| IntermediateDirectory="$(OutDir)/$(ProjectName)" | |||
| ConfigurationType="1" | |||
| CharacterSet="1" | |||
| WholeProgramOptimization="1" | |||
| > | |||
| <Tool | |||
| Name="VCPreBuildEventTool" | |||
| CommandLine="" | |||
| /> | |||
| <Tool | |||
| Name="VCCustomBuildTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXMLDataGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCWebServiceProxyGeneratorTool" | |||
| /> | |||
| <Tool | |||
| Name="VCMIDLTool" | |||
| /> | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| AdditionalIncludeDirectories="..\win32;..\pipi" | |||
| PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" | |||
| RuntimeLibrary="2" | |||
| UsePrecompiledHeader="0" | |||
| WarningLevel="3" | |||
| Detect64BitPortabilityProblems="true" | |||
| DebugInformationFormat="3" | |||
| /> | |||
| <Tool | |||
| Name="VCManagedResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCResourceCompilerTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPreLinkEventTool" | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| LinkIncremental="2" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="1" | |||
| OptimizeReferences="2" | |||
| EnableCOMDATFolding="2" | |||
| RandomizedBaseAddress="1" | |||
| DataExecutionPrevention="0" | |||
| TargetMachine="1" | |||
| /> | |||
| <Tool | |||
| Name="VCALinkTool" | |||
| /> | |||
| <Tool | |||
| Name="VCManifestTool" | |||
| /> | |||
| <Tool | |||
| Name="VCXDCMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCBscMakeTool" | |||
| /> | |||
| <Tool | |||
| Name="VCFxCopTool" | |||
| /> | |||
| <Tool | |||
| Name="VCAppVerifierTool" | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| /> | |||
| </Configuration> | |||
| </Configurations> | |||
| <References> | |||
| </References> | |||
| <Files> | |||
| <File | |||
| RelativePath="..\win32\config.h" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath=".\sharpen.c" | |||
| > | |||
| </File> | |||
| </Files> | |||
| <Globals> | |||
| </Globals> | |||
| </VisualStudioProject> | |||
| @@ -28,6 +28,7 @@ libpipi_la_SOURCES = \ | |||
| resize.c \ | |||
| dither.c \ | |||
| accessors.c \ | |||
| sequence.c \ | |||
| $(codec_sources) \ | |||
| $(paint_sources) \ | |||
| $(render_sources) \ | |||
| @@ -18,8 +18,8 @@ | |||
| <Configurations> | |||
| <Configuration | |||
| Name="Debug|Win32" | |||
| OutputDirectory="$(SolutionDir)/win32/$(ConfigurationName)/bin" | |||
| IntermediateDirectory="$(OutDir)/$(ProjectName)" | |||
| OutputDirectory="$(SolutionDir)\win32\$(ConfigurationName)\bin" | |||
| IntermediateDirectory="$(OutDir)\$(ProjectName)" | |||
| ConfigurationType="2" | |||
| > | |||
| <Tool | |||
| @@ -40,7 +40,7 @@ | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| Optimization="0" | |||
| AdditionalIncludeDirectories="..\win32;.;.." | |||
| AdditionalIncludeDirectories="..\win32;..\win32\ffmpeg\include" | |||
| PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPIPI_EXPORTS;__LIBPIPI__" | |||
| MinimalRebuild="true" | |||
| BasicRuntimeChecks="3" | |||
| @@ -61,9 +61,10 @@ | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| AdditionalDependencies="gdiplus.lib gdi32.lib user32.lib" | |||
| AdditionalDependencies="gdiplus.lib gdi32.lib user32.lib avutil-50.lib avformat-52.lib avcodec-52.lib swscale-0.lib" | |||
| OutputFile="$(OutDir)\$(ProjectName)-0.dll" | |||
| LinkIncremental="2" | |||
| AdditionalLibraryDirectories="..\win32\ffmpeg\lib" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="2" | |||
| RandomizedBaseAddress="1" | |||
| @@ -90,12 +91,13 @@ | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| CommandLine="xcopy /Y /D $(SolutionDir)\win32\ffmpeg\lib\*.dll $(OutDir)" | |||
| /> | |||
| </Configuration> | |||
| <Configuration | |||
| Name="Release|Win32" | |||
| OutputDirectory="$(SolutionDir)/win32/$(ConfigurationName)/bin" | |||
| IntermediateDirectory="$(OutDir)/$(ProjectName)" | |||
| OutputDirectory="$(SolutionDir)\win32\$(ConfigurationName)\bin" | |||
| IntermediateDirectory="$(OutDir)\$(ProjectName)" | |||
| ConfigurationType="2" | |||
| > | |||
| <Tool | |||
| @@ -115,7 +117,7 @@ | |||
| /> | |||
| <Tool | |||
| Name="VCCLCompilerTool" | |||
| AdditionalIncludeDirectories="..\win32;.;.." | |||
| AdditionalIncludeDirectories="..\win32;..;.;..\win32\ffmpeg\include" | |||
| PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPIPI_EXPORTS;__LIBPIPI__" | |||
| RuntimeLibrary="2" | |||
| UsePrecompiledHeader="0" | |||
| @@ -134,9 +136,10 @@ | |||
| /> | |||
| <Tool | |||
| Name="VCLinkerTool" | |||
| AdditionalDependencies="gdiplus.lib gdi32.lib user32.lib" | |||
| AdditionalDependencies="gdiplus.lib gdi32.lib user32.lib avutil-50.lib avformat-52.lib avcodec-52.lib swscale-0.lib" | |||
| OutputFile="$(OutDir)\$(ProjectName)-0.dll" | |||
| LinkIncremental="2" | |||
| AdditionalLibraryDirectories="..\win32\ffmpeg\lib" | |||
| GenerateDebugInformation="true" | |||
| SubSystem="2" | |||
| OptimizeReferences="2" | |||
| @@ -165,6 +168,7 @@ | |||
| /> | |||
| <Tool | |||
| Name="VCPostBuildEventTool" | |||
| CommandLine="xcopy /Y /D $(SolutionDir)\win32\ffmpeg\lib\*.dll $(OutDir)" | |||
| /> | |||
| </Configuration> | |||
| </Configurations> | |||
| @@ -238,6 +242,10 @@ | |||
| RelativePath=".\resize.c" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath=".\sequence.c" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath=".\stock.c" | |||
| > | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * libpipi Pathetic image processing interface library | |||
| * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> | |||
| * Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net> | |||
| * 2008 Jean-Yves Lamoureux <jylam@lnxscene.org | |||
| * All Rights Reserved | |||
| * | |||
| @@ -107,6 +107,9 @@ typedef struct pipi_tile pipi_tile_t; | |||
| /* pipi_image_t: the main image type */ | |||
| typedef struct pipi_image pipi_image_t; | |||
| /* pipi_sequence_t: the image sequence type */ | |||
| typedef struct pipi_sequence pipi_sequence_t; | |||
| /* pipi_context_t: the processing stack */ | |||
| typedef struct pipi_context pipi_context_t; | |||
| @@ -234,6 +237,10 @@ __extern int pipi_get_image_histogram(pipi_image_t *, pipi_histogram_t *, int); | |||
| __extern int pipi_free_histogram(pipi_histogram_t*); | |||
| __extern int pipi_render_histogram(pipi_image_t *, pipi_histogram_t*, int); | |||
| __extern pipi_sequence_t *pipi_open_sequence(char *, int, int, int); | |||
| __extern int pipi_feed_sequence(pipi_sequence_t *, uint8_t *, int, int); | |||
| __extern int pipi_close_sequence(pipi_sequence_t *); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * libpipi Pathetic image processing interface library | |||
| * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org> | |||
| * Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net> | |||
| * All Rights Reserved | |||
| * | |||
| * $Id$ | |||
| @@ -82,6 +82,13 @@ struct pipi_image | |||
| int (*codec_free)(pipi_image_t *); | |||
| }; | |||
| struct pipi_sequence | |||
| { | |||
| int w, h, fps; | |||
| void *codec_priv; | |||
| }; | |||
| struct pipi_context | |||
| { | |||
| int nimages; | |||
| @@ -0,0 +1,279 @@ | |||
| /* | |||
| * libpipi Pathetic image processing interface library | |||
| * Copyright (c) 2004-2009 Sam Hocevar <sam@hocevar.net> | |||
| * All Rights Reserved | |||
| * | |||
| * $Id$ | |||
| * | |||
| * This library is free software. It comes without any warranty, to | |||
| * the extent permitted by applicable law. You can redistribute it | |||
| * and/or modify it under the terms of the Do What The Fuck You Want | |||
| * To Public License, Version 2, as published by Sam Hocevar. See | |||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||
| */ | |||
| /* | |||
| * codec.c: image I/O functions | |||
| */ | |||
| #include "config.h" | |||
| #if defined _WIN32 | |||
| # undef _CRT_SECURE_NO_WARNINGS | |||
| # define _CRT_SECURE_NO_WARNINGS /* I know how to use snprintf, thank you */ | |||
| # define snprintf _snprintf | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #if defined USE_FFMPEG | |||
| # include <libavformat/avformat.h> | |||
| # include <libswscale/swscale.h> | |||
| #endif | |||
| #include "pipi.h" | |||
| #include "pipi_internals.h" | |||
| #if defined USE_FFMPEG | |||
| typedef struct | |||
| { | |||
| uint8_t *buf; | |||
| size_t buf_len; | |||
| AVFormatContext *fmt_ctx; | |||
| AVStream *stream; | |||
| AVCodecContext *cod_ctx; | |||
| AVCodec *codec; | |||
| AVFrame *frame; | |||
| struct SwsContext *sws_ctx; | |||
| int src_width, src_height; | |||
| } | |||
| ffmpeg_codec_t; | |||
| #endif | |||
| #define PAR_NUM 1 | |||
| #define PAR_DEN 1 | |||
| #define BITRATE (16 * 1024 * 1024) | |||
| pipi_sequence_t *pipi_open_sequence(char *file, int width, int height, int fps) | |||
| { | |||
| #if defined USE_FFMPEG | |||
| static int initialised = 0; | |||
| pipi_sequence_t *seq; | |||
| ffmpeg_codec_t *ff; | |||
| uint8_t *tmp; | |||
| seq = malloc(sizeof(pipi_sequence_t)); | |||
| seq->w = width; | |||
| seq->h = height; | |||
| seq->fps = fps; | |||
| ff = malloc(sizeof(ffmpeg_codec_t)); | |||
| memset(ff, 0, sizeof(*ff)); | |||
| seq->codec_priv = ff; | |||
| if (!initialised) | |||
| { | |||
| av_register_all(); | |||
| initialised = 1; | |||
| } | |||
| ff->fmt_ctx = avformat_alloc_context(); | |||
| if (!ff->fmt_ctx) | |||
| goto error; | |||
| /* Careful here: the Win32 snprintf doesn't seem to add a trailing | |||
| * zero to the truncated output. */ | |||
| snprintf(ff->fmt_ctx->filename, sizeof(ff->fmt_ctx->filename), | |||
| file); | |||
| ff->fmt_ctx->filename[sizeof(ff->fmt_ctx->filename) - 1] = '\0'; | |||
| ff->fmt_ctx->oformat = guess_format(NULL, file, NULL); | |||
| if (!ff->fmt_ctx->oformat) | |||
| ff->fmt_ctx->oformat = guess_format("mpeg", NULL, NULL); | |||
| if (!ff->fmt_ctx->oformat) | |||
| goto error; | |||
| ff->stream = av_new_stream(ff->fmt_ctx, 0); | |||
| if (!ff->stream) | |||
| goto error; | |||
| ff->stream->sample_aspect_ratio.num = PAR_NUM; | |||
| ff->stream->sample_aspect_ratio.den = PAR_DEN; | |||
| ff->cod_ctx = ff->stream->codec; | |||
| ff->cod_ctx->width = width; | |||
| ff->cod_ctx->height = height; | |||
| ff->cod_ctx->sample_aspect_ratio.num = PAR_NUM; | |||
| ff->cod_ctx->sample_aspect_ratio.den = PAR_DEN; | |||
| ff->cod_ctx->codec_id = ff->fmt_ctx->oformat->video_codec; | |||
| ff->cod_ctx->codec_type = CODEC_TYPE_VIDEO; | |||
| ff->cod_ctx->bit_rate = BITRATE; | |||
| ff->cod_ctx->time_base.num = 1; | |||
| ff->cod_ctx->time_base.den = fps; | |||
| ff->cod_ctx->gop_size = fps * 3 / 4; /* empirical */ | |||
| ff->cod_ctx->pix_fmt = PIX_FMT_YUV420P; /* send YUV 420 */ | |||
| if (ff->cod_ctx->codec_id == CODEC_ID_MPEG2VIDEO) | |||
| ff->cod_ctx->max_b_frames = 2; | |||
| if (ff->cod_ctx->codec_id == CODEC_ID_MPEG1VIDEO) | |||
| ff->cod_ctx->mb_decision = 2; | |||
| if (ff->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) | |||
| ff->cod_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; | |||
| if (av_set_parameters(ff->fmt_ctx, NULL) < 0) | |||
| goto error; | |||
| ff->codec = avcodec_find_encoder(ff->cod_ctx->codec_id); | |||
| if (!ff->codec) | |||
| goto error; | |||
| if (avcodec_open(ff->cod_ctx, ff->codec) < 0) | |||
| goto error; | |||
| ff->frame = avcodec_alloc_frame(); | |||
| if (!ff->frame) | |||
| goto error; | |||
| tmp = (uint8_t *)av_malloc(avpicture_get_size(ff->cod_ctx->pix_fmt, | |||
| ff->cod_ctx->width, | |||
| ff->cod_ctx->height)); | |||
| if (!tmp) | |||
| goto error; | |||
| avpicture_fill((AVPicture *)ff->frame, tmp, ff->cod_ctx->pix_fmt, | |||
| ff->cod_ctx->width, ff->cod_ctx->height); | |||
| if (!(ff->fmt_ctx->flags & AVFMT_NOFILE)) | |||
| if (url_fopen(&ff->fmt_ctx->pb, file, URL_WRONLY) < 0) | |||
| goto error; | |||
| ff->buf_len = 64 * 1024 * 1024; | |||
| ff->buf = (uint8_t *)av_malloc(ff->buf_len); | |||
| av_write_header(ff->fmt_ctx); | |||
| return seq; | |||
| error: | |||
| pipi_close_sequence(seq); | |||
| return NULL; | |||
| #else | |||
| return NULL; | |||
| #endif | |||
| } | |||
| int pipi_feed_sequence(pipi_sequence_t *seq, uint8_t *buffer, int width, int height) | |||
| { | |||
| #if defined USE_FFMPEG | |||
| AVPacket packet; | |||
| size_t bytes; | |||
| int pitch; | |||
| ffmpeg_codec_t *ff = (ffmpeg_codec_t *)seq->codec_priv; | |||
| if (ff->src_width != width || ff->src_height != height) | |||
| { | |||
| ff->src_width = width; | |||
| ff->src_height = height; | |||
| if (ff->sws_ctx) | |||
| sws_freeContext(ff->sws_ctx); | |||
| ff->sws_ctx = NULL; | |||
| } | |||
| if (!ff->sws_ctx) | |||
| ff->sws_ctx = sws_getContext(width, height, PIX_FMT_RGB32, | |||
| ff->cod_ctx->width, | |||
| ff->cod_ctx->height, | |||
| ff->cod_ctx->pix_fmt, SWS_BICUBIC, | |||
| NULL, NULL, NULL); | |||
| if (!ff->sws_ctx) | |||
| return -1; | |||
| pitch = width * 4; | |||
| sws_scale(ff->sws_ctx, &buffer, &pitch, 0, height, | |||
| ff->frame->data, ff->frame->linesize); | |||
| bytes = avcodec_encode_video(ff->cod_ctx, ff->buf, | |||
| ff->buf_len, ff->frame); | |||
| if (bytes <= 0) | |||
| return 0; | |||
| av_init_packet(&packet); | |||
| if (ff->cod_ctx->coded_frame->pts != 0x8000000000000000LL) | |||
| packet.pts = av_rescale_q(ff->cod_ctx->coded_frame->pts, | |||
| ff->cod_ctx->time_base, ff->stream->time_base); | |||
| if (ff->cod_ctx->coded_frame->key_frame) | |||
| packet.flags |= PKT_FLAG_KEY; | |||
| packet.stream_index = 0; | |||
| packet.data = ff->buf; | |||
| packet.size = bytes; | |||
| if (av_interleaved_write_frame(ff->fmt_ctx, &packet) < 0) | |||
| return -1; | |||
| #endif | |||
| return 0; | |||
| } | |||
| int pipi_close_sequence(pipi_sequence_t *seq) | |||
| { | |||
| #if defined USE_FFMPEG | |||
| ffmpeg_codec_t *ff = (ffmpeg_codec_t *)seq->codec_priv; | |||
| if (ff->fmt_ctx) | |||
| { | |||
| av_write_trailer(ff->fmt_ctx); | |||
| } | |||
| if (ff->buf) | |||
| { | |||
| av_free(ff->buf); | |||
| ff->buf = NULL; | |||
| } | |||
| if (ff->cod_ctx) | |||
| { | |||
| avcodec_close(ff->cod_ctx); | |||
| ff->cod_ctx = NULL; | |||
| } | |||
| if (ff->frame) | |||
| { | |||
| av_free(ff->frame->data[0]); | |||
| av_free(ff->frame); | |||
| ff->frame = NULL; | |||
| } | |||
| if (ff->fmt_ctx) | |||
| { | |||
| av_freep(&ff->fmt_ctx->streams[0]->codec); | |||
| ff->codec = NULL; | |||
| av_freep(&ff->fmt_ctx->streams[0]); | |||
| ff->stream = NULL; | |||
| if (!(ff->fmt_ctx->flags & AVFMT_NOFILE)) | |||
| url_fclose(ff->fmt_ctx->pb); | |||
| av_free(ff->fmt_ctx); | |||
| ff->fmt_ctx = NULL; | |||
| } | |||
| if (ff->sws_ctx) | |||
| { | |||
| sws_freeContext(ff->sws_ctx); | |||
| ff->sws_ctx = NULL; | |||
| ff->src_width = ff->src_height = 0; | |||
| } | |||
| free(ff); | |||
| free(seq); | |||
| #endif | |||
| return 0; | |||
| } | |||
| @@ -43,6 +43,7 @@ | |||
| #define USE_GDI 1 | |||
| #define USE_GDIPLUS 1 | |||
| /* #undef USE_COCOA */ | |||
| #define USE_FFMPEG 1 | |||
| /* #undef const */ | |||
| #ifndef __cplusplus | |||
| #define inline __inline | |||