EDN Admin
Well-known member
I just downloaded the msys and also downloaded the ffmpeg snapshot and also downloaded MinGW
Now i have this CPP file ://#define UINT64_C (uint64_t);
/*
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "gdiplus.lib")
#include <windows.h>
#include <gdiplus.h>
#include <GdiPlusEnums.h>
using namespace Gdiplus;
*/
extern "C" {
#include <stdint.h>
#include <math.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
/*
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
*/
//#include "libavcodecavcodec.h"
//WCHAR *fname; // windows.h is needed for this type
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
int total_frame_counter;
FILE *f;
AVFrame *frame;
AVPacket pkt;
int codec_id;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
int errn;
char temp_buffer[1024];
__declspec(thread) AVCodec* current_codec = NULL;
void Encoder_init()
{
avcodec_register_all();
/* find the mpeg1 video encoder */
codec_id = CODEC_ID_MPEG1VIDEO;
//codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
//codec = avcodec_find_encoder(AV_CODEC_ID_ZMBV);
codec = avcodec_find_encoder((AVCodecID)codec_id);
for (int j=CODEC_ID_MPEG1VIDEO;j<AV_CODEC_ID_VP9;j++)
{
codec = avcodec_find_encoder((AVCodecID)j);
}
codec_id = AV_CODEC_ID_H263P;
codec_id = AV_CODEC_ID_H264;
//codec_id = CODEC_ID_MPEG1VIDEO;
codec_id = CODEC_ID_MPEG4;
codec = avcodec_find_encoder((AVCodecID)codec_id);
if (!codec) {
fprintf(stderr, "Codec not foundn");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec contextn");
exit(1);
}
/* put sample parameters */
c->bit_rate = 3200000;//400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
//c->time_base= (AVRational){1,25};
c->time_base.num=1;c->time_base.den=25;
//c->gop_size = 10; /* emit one intra frame every ten frames */
c->gop_size = 10; /* emit one intra frame every ten frames */
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P; // original
//c->pix_fmt = AV_PIX_FMT_RGB24; // we prefer rgb24 because maybe Bitmap .net class can support this exact format
if(codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
}
void Encoder_config( int width , int height )
{
c->width = width;
c->height = height;
}
void Encoder_deinit()
{
av_free(c);
}
void Encoder_start(char *filename)
{
printf("Encode video file %sn", filename);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codecn");
exit(1);
}
// f = fopen(filename, "wb");
errn = fopen_s(&f,filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %sn", filename);
exit(1);
}
frame = avcodec_alloc_frame();
if (!frame) {
fprintf(stderr, "Could not allocate video framen");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
//ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
// c->pix_fmt, 32);
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 1); // we probably need alignment of 1 because this is the format of bitmap (after using lockbits)
// temp_data_ptr = frame->data[0];
/*
frame->data[0] = (uint8_t*)av_malloc(1000000);
frame->data[1] = (uint8_t*)av_malloc(1000000);
frame->data[2] = (uint8_t*)av_malloc(1000000);
frame->data[3] = (uint8_t*)av_malloc(1000000);
frame->data[4] = (uint8_t*)av_malloc(1000000);
frame->data[5] = (uint8_t*)av_malloc(1000000);
frame->data[6] = (uint8_t*)av_malloc(1000000);
frame->data[7] = (uint8_t*)av_malloc(1000000);
//if (frame->data[7]==0) {
*/
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffern");
exit(1);
}
total_frame_counter=0;
}
void Encoder_push_frame(uint8_t *frame_data_rgb24bpp_fmt)
{
// encode a single frame
// for (copying from rgb24bpp to yuv420p format)
// data[0] is Y , size = number of pixels
// data[1] is U , size = number of pixels /4
// data[2] is V , size = number of pixels /4
// ref : wikipedia :
int total_pixels = frame->width*frame->height;
int total_rgb_sz=total_pixels*3;
double Wr=0.299,Wb=0.114,Wg=1-Wr-Wb;
double Umax=0.436,Vmax=0.615;
double Y,U,V;
double R,G,B;
int Yndx=0,UVndx=0;
int ndx=0;
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
fflush(stdout);
for (i=0;i<total_rgb_sz;i+=3)
{
R = frame_data_rgb24bpp_fmt;
G = frame_data_rgb24bpp_fmt[i+1];
B = frame_data_rgb24bpp_fmt[i+2];
Y = Wr*R + Wg*G + Wb*B;
Y = (R+G+B)/3;
frame->data[0][Yndx] = (uint8_t)(Y); // yuv pixel format is 12bpp... is this means 4bits for y 4bits for U and 4 bits for V ? so max value is 15 .. not sure... seems wierd..
if ( ( (ndx/frame->width)%2==0 ) && ((ndx%2)==0) ) // U V are set for every 2x2 pixels.. (and not for every pixel..) ( so we enter the if for every even line and every even pixel..)
{
// we take into account only one of the 2x2 pixels... (but it would be more accurate to average all four pixels.. and then to calc. U and V.. but it might involve a little more code..
// maybe next time... and only if it will not cost too much cpu time.
U = 0.492*(B-Y);
V = 0.877*(R-Y);
U = 128;//0.492*255;
V = 128;//0.877*255;
V= 128+0.492*(B-Y);
U= 128+0.877*(R-Y);
V= 128+(B-Y);
U= 128+(R-Y);
frame->data[1][UVndx] = (int8_t)(U);
frame->data[2][UVndx] = (int8_t)(V);
UVndx++;
}
Yndx++;
ndx++;
}
frame->pts = total_frame_counter;
total_frame_counter++;
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding framen");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)n", total_frame_counter, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
void Encoder_close()
{
/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding framen");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_close(c);
av_freep(&frame->data[0]);
// av_freep(&temp_data_ptr);
avcodec_free_frame(&frame);
printf("n");
}
/*const char* Encoder_GetNextCodecName()
{
current_codec = av_codec_next(current_codec);
while (current_codec != NULL)
{
/* this is optional...
if (!av_codec_is_encoder(current_codec))
{
current_codec = av_codec_next(current_codec);
continue;
}
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
current_codec = NULL;
return Encoder_GetNextCodecName();
}*/
/*const char *Encoder_GetCodecName( int id )
{
return avcodec_get_name( (AVCodecID)id );
}*/
bool Encoder_MoveToNextCodec()
{
current_codec = av_codec_next(current_codec);
return (current_codec != NULL);
}
bool Encoder_MoveToFirstCodec()
{
current_codec = NULL;
return Encoder_MoveToNextCodec();
}
int Encoder_GetCurrentCodecID()
{
return current_codec->id;
}
const char* Encoder_GetCurrentCodecName()
{
if (current_codec != NULL)
return current_codec->name;
return "";
}
int Encoder_GetCurrentCodecType()
{
if (current_codec != NULL)
return (int) current_codec->type;
return AVMEDIA_TYPE_UNKNOWN;
}
const char* Encoder_av_get_media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
//AVCodecID
case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
case AVMEDIA_TYPE_AUDIO: return "audio";
case AVMEDIA_TYPE_DATA: return "data";
case AVMEDIA_TYPE_NB: return "nb";
case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
case AVMEDIA_TYPE_UNKNOWN: return "unknown";
case AVMEDIA_TYPE_VIDEO: return "video";
default: return NULL;
}
}
// the function will fill outbuf with all the pixels formats for this codec... but no more than buf_sz... so we wont run down some memory not of the buffer
{
if (current_codec == NULL)
return 0;
int i=0;
while ( (i<buf_sz) && (current_codec->pix_fmts!=-1) )
{
outbuf = current_codec->pix_fmts;
i++;
}
return i;
// the function returns the actual size of the buffer
}
} // end of extern "C"
I renamed it on my hard disk to ENCODER.c from .cpp
And i have in the same directory the file: Makefile.mak
I want to create a dll file from the ENCODER.c so i can use it later on my c++ project.
So in the msys directory i run msys.bat
Then i went to the directory where the Makefile.mak is and also the ENCODER.c is and i typed:
Makefile
But what i get is an error: Makefile: command not found
What am i doing wrong ?
This is the Makefile.mak content:include $(SUBDIR)../config.mak
NAME = myencoderdll
# I think the header are not important..it more or less tells about dependency.. for now does not matter
# the h files should be h files we use in encoder.c. ... i think.. never mind for now
# so put in this dir encoder.c (our encoder.cpp .. rename it..) and try to compile
HEADERS = adler32.h
xtea.h
HEADERS-$(CONFIG_LZO) += lzo.h
HEADERS-$(CONFIG_OPENCL) += opencl.h
ARCH_HEADERS = bswap.h
intmath.h
intreadwrite.h
timer.h
BUILT_HEADERS = avconfig.h
OBJS = encoder.o
# dont know what is everything below..
OBJS-$(CONFIG_LZO) += lzo.o
OBJS-$(CONFIG_OPENCL) += opencl.o opencl_internal.o
OBJS += $(COMPAT_OBJS:%=../compat/%)
SKIPHEADERS = old_pix_fmts.h
SKIPHEADERS-$(HAVE_ATOMICS_GCC) += atomic_gcc.h
SKIPHEADERS-$(HAVE_ATOMICS_SUNCC) += atomic_suncc.h
SKIPHEADERS-$(HAVE_ATOMICS_WIN32) += atomic_win32.h
SKIPHEADERS-$(CONFIG_OPENCL) += opencl.h
I removed the headers files from there .
What am i doing wrong ?
I tried ot copy now another Makefile which is content not the same as the Makefile.mak
Tried to run this Makefile and got errors on each line: command not found
So what can i do ?
View the full article
Now i have this CPP file ://#define UINT64_C (uint64_t);
/*
#pragma comment(lib, "Gdi32.lib")
#pragma comment(lib, "User32.lib")
#pragma comment(lib, "gdiplus.lib")
#include <windows.h>
#include <gdiplus.h>
#include <GdiPlusEnums.h>
using namespace Gdiplus;
*/
extern "C" {
#include <stdint.h>
#include <math.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
/*
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
*/
//#include "libavcodecavcodec.h"
//WCHAR *fname; // windows.h is needed for this type
AVCodec *codec;
AVCodecContext *c= NULL;
int i, ret, x, y, got_output;
int total_frame_counter;
FILE *f;
AVFrame *frame;
AVPacket pkt;
int codec_id;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
int errn;
char temp_buffer[1024];
__declspec(thread) AVCodec* current_codec = NULL;
void Encoder_init()
{
avcodec_register_all();
/* find the mpeg1 video encoder */
codec_id = CODEC_ID_MPEG1VIDEO;
//codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
//codec = avcodec_find_encoder(AV_CODEC_ID_ZMBV);
codec = avcodec_find_encoder((AVCodecID)codec_id);
for (int j=CODEC_ID_MPEG1VIDEO;j<AV_CODEC_ID_VP9;j++)
{
codec = avcodec_find_encoder((AVCodecID)j);
}
codec_id = AV_CODEC_ID_H263P;
codec_id = AV_CODEC_ID_H264;
//codec_id = CODEC_ID_MPEG1VIDEO;
codec_id = CODEC_ID_MPEG4;
codec = avcodec_find_encoder((AVCodecID)codec_id);
if (!codec) {
fprintf(stderr, "Codec not foundn");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec contextn");
exit(1);
}
/* put sample parameters */
c->bit_rate = 3200000;//400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
//c->time_base= (AVRational){1,25};
c->time_base.num=1;c->time_base.den=25;
//c->gop_size = 10; /* emit one intra frame every ten frames */
c->gop_size = 10; /* emit one intra frame every ten frames */
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P; // original
//c->pix_fmt = AV_PIX_FMT_RGB24; // we prefer rgb24 because maybe Bitmap .net class can support this exact format
if(codec_id == AV_CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
}
void Encoder_config( int width , int height )
{
c->width = width;
c->height = height;
}
void Encoder_deinit()
{
av_free(c);
}
void Encoder_start(char *filename)
{
printf("Encode video file %sn", filename);
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codecn");
exit(1);
}
// f = fopen(filename, "wb");
errn = fopen_s(&f,filename, "wb");
if (!f) {
fprintf(stderr, "Could not open %sn", filename);
exit(1);
}
frame = avcodec_alloc_frame();
if (!frame) {
fprintf(stderr, "Could not allocate video framen");
exit(1);
}
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
/* the image can be allocated by any means and av_image_alloc() is
* just the most convenient way if av_malloc() is to be used */
//ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
// c->pix_fmt, 32);
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
c->pix_fmt, 1); // we probably need alignment of 1 because this is the format of bitmap (after using lockbits)
// temp_data_ptr = frame->data[0];
/*
frame->data[0] = (uint8_t*)av_malloc(1000000);
frame->data[1] = (uint8_t*)av_malloc(1000000);
frame->data[2] = (uint8_t*)av_malloc(1000000);
frame->data[3] = (uint8_t*)av_malloc(1000000);
frame->data[4] = (uint8_t*)av_malloc(1000000);
frame->data[5] = (uint8_t*)av_malloc(1000000);
frame->data[6] = (uint8_t*)av_malloc(1000000);
frame->data[7] = (uint8_t*)av_malloc(1000000);
//if (frame->data[7]==0) {
*/
if (ret < 0) {
fprintf(stderr, "Could not allocate raw picture buffern");
exit(1);
}
total_frame_counter=0;
}
void Encoder_push_frame(uint8_t *frame_data_rgb24bpp_fmt)
{
// encode a single frame
// for (copying from rgb24bpp to yuv420p format)
// data[0] is Y , size = number of pixels
// data[1] is U , size = number of pixels /4
// data[2] is V , size = number of pixels /4
// ref : wikipedia :
int total_pixels = frame->width*frame->height;
int total_rgb_sz=total_pixels*3;
double Wr=0.299,Wb=0.114,Wg=1-Wr-Wb;
double Umax=0.436,Vmax=0.615;
double Y,U,V;
double R,G,B;
int Yndx=0,UVndx=0;
int ndx=0;
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
fflush(stdout);
for (i=0;i<total_rgb_sz;i+=3)
{
R = frame_data_rgb24bpp_fmt;
G = frame_data_rgb24bpp_fmt[i+1];
B = frame_data_rgb24bpp_fmt[i+2];
Y = Wr*R + Wg*G + Wb*B;
Y = (R+G+B)/3;
frame->data[0][Yndx] = (uint8_t)(Y); // yuv pixel format is 12bpp... is this means 4bits for y 4bits for U and 4 bits for V ? so max value is 15 .. not sure... seems wierd..
if ( ( (ndx/frame->width)%2==0 ) && ((ndx%2)==0) ) // U V are set for every 2x2 pixels.. (and not for every pixel..) ( so we enter the if for every even line and every even pixel..)
{
// we take into account only one of the 2x2 pixels... (but it would be more accurate to average all four pixels.. and then to calc. U and V.. but it might involve a little more code..
// maybe next time... and only if it will not cost too much cpu time.
U = 0.492*(B-Y);
V = 0.877*(R-Y);
U = 128;//0.492*255;
V = 128;//0.877*255;
V= 128+0.492*(B-Y);
U= 128+0.877*(R-Y);
V= 128+(B-Y);
U= 128+(R-Y);
frame->data[1][UVndx] = (int8_t)(U);
frame->data[2][UVndx] = (int8_t)(V);
UVndx++;
}
Yndx++;
ndx++;
}
frame->pts = total_frame_counter;
total_frame_counter++;
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding framen");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)n", total_frame_counter, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
void Encoder_close()
{
/* get the delayed frames */
for (got_output = 1; got_output; i++) {
fflush(stdout);
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding framen");
exit(1);
}
if (got_output) {
printf("Write frame %3d (size=%5d)n", i, pkt.size);
fwrite(pkt.data, 1, pkt.size, f);
av_free_packet(&pkt);
}
}
fwrite(endcode, 1, sizeof(endcode), f);
fclose(f);
avcodec_close(c);
av_freep(&frame->data[0]);
// av_freep(&temp_data_ptr);
avcodec_free_frame(&frame);
printf("n");
}
/*const char* Encoder_GetNextCodecName()
{
current_codec = av_codec_next(current_codec);
while (current_codec != NULL)
{
/* this is optional...
if (!av_codec_is_encoder(current_codec))
{
current_codec = av_codec_next(current_codec);
continue;
}
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
current_codec = NULL;
return Encoder_GetNextCodecName();
}*/
/*const char *Encoder_GetCodecName( int id )
{
return avcodec_get_name( (AVCodecID)id );
}*/
bool Encoder_MoveToNextCodec()
{
current_codec = av_codec_next(current_codec);
return (current_codec != NULL);
}
bool Encoder_MoveToFirstCodec()
{
current_codec = NULL;
return Encoder_MoveToNextCodec();
}
int Encoder_GetCurrentCodecID()
{
return current_codec->id;
}
const char* Encoder_GetCurrentCodecName()
{
if (current_codec != NULL)
return current_codec->name;
return "";
}
int Encoder_GetCurrentCodecType()
{
if (current_codec != NULL)
return (int) current_codec->type;
return AVMEDIA_TYPE_UNKNOWN;
}
const char* Encoder_av_get_media_type_string(enum AVMediaType media_type)
{
switch (media_type) {
//AVCodecID
case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
case AVMEDIA_TYPE_AUDIO: return "audio";
case AVMEDIA_TYPE_DATA: return "data";
case AVMEDIA_TYPE_NB: return "nb";
case AVMEDIA_TYPE_SUBTITLE: return "subtitle";
case AVMEDIA_TYPE_UNKNOWN: return "unknown";
case AVMEDIA_TYPE_VIDEO: return "video";
default: return NULL;
}
}
// the function will fill outbuf with all the pixels formats for this codec... but no more than buf_sz... so we wont run down some memory not of the buffer
{
if (current_codec == NULL)
return 0;
int i=0;
while ( (i<buf_sz) && (current_codec->pix_fmts!=-1) )
{
outbuf = current_codec->pix_fmts;
i++;
}
return i;
// the function returns the actual size of the buffer
}
} // end of extern "C"
I renamed it on my hard disk to ENCODER.c from .cpp
And i have in the same directory the file: Makefile.mak
I want to create a dll file from the ENCODER.c so i can use it later on my c++ project.
So in the msys directory i run msys.bat
Then i went to the directory where the Makefile.mak is and also the ENCODER.c is and i typed:
Makefile
But what i get is an error: Makefile: command not found
What am i doing wrong ?
This is the Makefile.mak content:include $(SUBDIR)../config.mak
NAME = myencoderdll
# I think the header are not important..it more or less tells about dependency.. for now does not matter
# the h files should be h files we use in encoder.c. ... i think.. never mind for now
# so put in this dir encoder.c (our encoder.cpp .. rename it..) and try to compile
HEADERS = adler32.h
xtea.h
HEADERS-$(CONFIG_LZO) += lzo.h
HEADERS-$(CONFIG_OPENCL) += opencl.h
ARCH_HEADERS = bswap.h
intmath.h
intreadwrite.h
timer.h
BUILT_HEADERS = avconfig.h
OBJS = encoder.o
# dont know what is everything below..
OBJS-$(CONFIG_LZO) += lzo.o
OBJS-$(CONFIG_OPENCL) += opencl.o opencl_internal.o
OBJS += $(COMPAT_OBJS:%=../compat/%)
SKIPHEADERS = old_pix_fmts.h
SKIPHEADERS-$(HAVE_ATOMICS_GCC) += atomic_gcc.h
SKIPHEADERS-$(HAVE_ATOMICS_SUNCC) += atomic_suncc.h
SKIPHEADERS-$(HAVE_ATOMICS_WIN32) += atomic_win32.h
SKIPHEADERS-$(CONFIG_OPENCL) += opencl.h
I removed the headers files from there .
What am i doing wrong ?
I tried ot copy now another Makefile which is content not the same as the Makefile.mak
Tried to run this Makefile and got errors on each line: command not found
So what can i do ?
View the full article