hedgewars/avwrapper.c
author Stepan777 <stepik-777@mail.ru>
Sun, 24 Jun 2012 20:57:02 +0400
changeset 7280 fd707afbc3a2
parent 7235 baa69bd025d9
child 7282 c65992e2d794
permissions -rw-r--r--
pagevideos is now much better that before: 1. Display list of video files. 2. For each file in progress display progress bar. 3. Description for each file (size, duration etc). 4. It is possible to remove and rename files. 5. Video file can be launched in external media player. 6. ... also fixed some bugs http://postimage.org/image/hk87cuqm9/
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     1
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     2
#include <stdlib.h>
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     3
#include <stdio.h>
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
     4
#include <stdint.h>
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     5
#include <string.h>
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     6
#include <stdarg.h>
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     7
#include "libavformat/avformat.h"
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     8
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
     9
static AVFormatContext* g_pContainer;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    10
static AVOutputFormat* g_pFormat;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    11
static AVStream* g_pAStream;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    12
static AVStream* g_pVStream;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    13
static AVFrame* g_pAFrame;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    14
static AVFrame* g_pVFrame;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    15
static AVCodec* g_pACodec;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    16
static AVCodec* g_pVCodec;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    17
static AVCodecContext* g_pAudio;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    18
static AVCodecContext* g_pVideo;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    19
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    20
static int g_Width, g_Height;
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
    21
static uint32_t g_Frequency, g_Channels;
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    22
static int g_VQuality, g_AQuality;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    23
static AVRational g_Framerate;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    24
static const char* g_pPreset;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    25
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    26
static FILE* g_pSoundFile;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    27
static int16_t* g_pSamples;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    28
static int g_NumSamples;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    29
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    30
/*
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    31
Initially I wrote code for latest ffmpeg, but on Linux (Ubuntu)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    32
only older version is available from repository. That's why you see here
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    33
all of this #if LIBAVCODEC_VERSION_MAJOR < 54.
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    34
Actually, it may be possible to remove code for newer version
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    35
and use only code for older version.
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    36
*/
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    37
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    38
#if LIBAVCODEC_VERSION_MAJOR < 54
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    39
#define OUTBUFFER_SIZE 200000
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    40
static uint8_t g_OutBuffer[OUTBUFFER_SIZE];
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    41
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    42
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    43
// pointer to function from hwengine (uUtils.pas)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    44
static void (*AddFileLogRaw)(const char* pString);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    45
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    46
static void FatalError(const char* pFmt, ...)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    47
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    48
    const char Buffer[1024];
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    49
    va_list VaArgs;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    50
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    51
    va_start(VaArgs, pFmt);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    52
    vsnprintf(Buffer, 1024, pFmt, VaArgs);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    53
    va_end(VaArgs);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    54
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    55
    AddFileLogRaw("Error in av-wrapper: ");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    56
    AddFileLogRaw(Buffer);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    57
    AddFileLogRaw("\n");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    58
    exit(1);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    59
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    60
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    61
// Function to be called from libav for logging.
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    62
// Note: libav can call LogCallback from different threads
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    63
// (there is mutex in AddFileLogRaw).
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    64
static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    65
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    66
    const char Buffer[1024];
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    67
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    68
    vsnprintf(Buffer, 1024, pFmt, VaArgs);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    69
    AddFileLogRaw(Buffer);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    70
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    71
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    72
static void Log(const char* pFmt, ...)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    73
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    74
    const char Buffer[1024];
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    75
    va_list VaArgs;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    76
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    77
    va_start(VaArgs, pFmt);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    78
    vsnprintf(Buffer, 1024, pFmt, VaArgs);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    79
    va_end(VaArgs);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    80
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    81
    AddFileLogRaw(Buffer);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    82
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    83
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    84
static void AddAudioStream()
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    85
{
7235
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
    86
#if LIBAVFORMAT_VERSION_MAJOR >= 54
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    87
    g_pAStream = avformat_new_stream(g_pContainer, g_pACodec);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    88
#else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    89
    g_pAStream = av_new_stream(g_pContainer, 1);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    90
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    91
    if(!g_pAStream)
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
    92
    {
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
    93
        Log("Could not allocate audio stream");
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
    94
        return;
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
    95
    }
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    96
    g_pAStream->id = 1;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    97
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
    98
    g_pAudio = g_pAStream->codec;
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
    99
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   100
    avcodec_get_context_defaults3(g_pAudio, g_pACodec);
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   101
    g_pAudio->codec_id = g_pACodec->id;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   102
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   103
    // put parameters
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   104
    g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   105
    g_pAudio->sample_rate = g_Frequency;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   106
    g_pAudio->channels = g_Channels;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   107
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   108
    // set quality
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   109
    if (g_AQuality > 100)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   110
        g_pAudio->bit_rate = g_AQuality;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   111
    else
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   112
    {
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   113
        g_pAudio->flags |= CODEC_FLAG_QSCALE;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   114
        g_pAudio->global_quality = g_AQuality*FF_QP2LAMBDA;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   115
    }
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   116
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   117
    // some formats want stream headers to be separate
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   118
    if (g_pFormat->flags & AVFMT_GLOBALHEADER)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   119
        g_pAudio->flags |= CODEC_FLAG_GLOBAL_HEADER;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   120
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   121
    // open it
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   122
    if (avcodec_open2(g_pAudio, g_pACodec, NULL) < 0)
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   123
    {
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   124
        Log("Could not open audio codec %s", g_pACodec->long_name);
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   125
        return;
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   126
    }
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   127
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   128
#if LIBAVCODEC_VERSION_MAJOR >= 54
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   129
    if (g_pACodec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   130
#else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   131
    if (g_pAudio->frame_size == 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   132
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   133
        g_NumSamples = 4096;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   134
    else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   135
        g_NumSamples = g_pAudio->frame_size;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   136
    g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t));
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   137
    g_pAFrame = avcodec_alloc_frame();
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   138
    if (!g_pAFrame)
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   139
    {
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   140
        Log("Could not allocate frame");
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   141
        return;
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   142
    }
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   143
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   144
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   145
// returns non-zero if there is more sound
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   146
static int WriteAudioFrame()
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   147
{
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   148
    if (!g_pAStream)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   149
        return 0;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   150
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   151
    AVPacket Packet = { 0 };
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   152
    av_init_packet(&Packet);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   153
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   154
    int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   155
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   156
#if LIBAVCODEC_VERSION_MAJOR >= 54
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   157
    AVFrame* pFrame = NULL;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   158
    if (NumSamples > 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   159
    {
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   160
        g_pAFrame->nb_samples = NumSamples;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   161
        avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16,
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   162
                                 (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   163
        pFrame = g_pAFrame;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   164
    }
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   165
    // when NumSamples == 0 we still need to call encode_audio2 to flush
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   166
    int got_packet;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   167
    if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   168
        FatalError("avcodec_encode_audio2 failed");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   169
    if (!got_packet)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   170
        return 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   171
#else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   172
    if (NumSamples == 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   173
        return 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   174
    int BufferSize = OUTBUFFER_SIZE;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   175
    if (g_pAudio->frame_size == 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   176
        BufferSize = NumSamples*g_Channels*2;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   177
    Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   178
    if (Packet.size == 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   179
        return 1;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   180
    if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   181
        Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   182
    Packet.flags |= AV_PKT_FLAG_KEY;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   183
    Packet.data = g_OutBuffer;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   184
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   185
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   186
    // Write the compressed frame to the media file.
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   187
    Packet.stream_index = g_pAStream->index;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   188
    if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) 
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   189
        FatalError("Error while writing audio frame");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   190
    return 1;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   191
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   192
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   193
// add a video output stream
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   194
static void AddVideoStream()
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   195
{
7235
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   196
#if LIBAVFORMAT_VERSION_MAJOR >= 54
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   197
    g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   198
#else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   199
    g_pVStream = av_new_stream(g_pContainer, 0);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   200
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   201
    if (!g_pVStream)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   202
        FatalError("Could not allocate video stream");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   203
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   204
    g_pVideo = g_pVStream->codec;
7235
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   205
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   206
    avcodec_get_context_defaults3(g_pVideo, g_pVCodec);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   207
    g_pVideo->codec_id = g_pVCodec->id;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   208
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   209
    // put parameters
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   210
    // resolution must be a multiple of two
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   211
    g_pVideo->width = g_Width;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   212
    g_pVideo->height = g_Height;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   213
    /* time base: this is the fundamental unit of time (in seconds) in terms
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   214
       of which frame timestamps are represented. for fixed-fps content,
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   215
       timebase should be 1/framerate and timestamp increments should be
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   216
       identically 1. */
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   217
    g_pVideo->time_base.den = g_Framerate.num;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   218
    g_pVideo->time_base.num = g_Framerate.den;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   219
    //g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   220
    g_pVideo->pix_fmt = PIX_FMT_YUV420P;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   221
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   222
    // set quality
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   223
    if (g_VQuality > 100)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   224
        g_pVideo->bit_rate = g_VQuality;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   225
    else
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   226
    {
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   227
        g_pVideo->flags |= CODEC_FLAG_QSCALE;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   228
        g_pVideo->global_quality = g_VQuality*FF_QP2LAMBDA;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   229
    }
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   230
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   231
    AVDictionary* pDict = NULL;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   232
    if (strcmp(g_pVCodec->name, "libx264") == 0)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   233
        av_dict_set(&pDict, "preset", g_pPreset, 0);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   234
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   235
    // some formats want stream headers to be separate
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   236
    if (g_pFormat->flags & AVFMT_GLOBALHEADER)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   237
        g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   238
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   239
    // open the codec
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   240
    if (avcodec_open2(g_pVideo, g_pVCodec, &pDict) < 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   241
        FatalError("Could not open video codec %s", g_pVCodec->long_name);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   242
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   243
    g_pVFrame = avcodec_alloc_frame();
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   244
    if (!g_pVFrame)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   245
        FatalError("Could not allocate frame");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   246
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   247
    g_pVFrame->linesize[0] = g_Width;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   248
    g_pVFrame->linesize[1] = g_Width/2;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   249
    g_pVFrame->linesize[2] = g_Width/2;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   250
    g_pVFrame->linesize[3] = 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   251
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   252
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   253
static int WriteFrame(AVFrame* pFrame)
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   254
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   255
    double AudioTime, VideoTime;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   256
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   257
    // write interleaved audio frame
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   258
    if (g_pAStream)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   259
    {
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   260
        VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   261
        do
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   262
            AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   263
        while (AudioTime < VideoTime && WriteAudioFrame());
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   264
    }
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   265
    
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   266
    if (!g_pVStream)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   267
        return 0;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   268
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   269
    AVPacket Packet;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   270
    av_init_packet(&Packet);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   271
    Packet.data = NULL;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   272
    Packet.size = 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   273
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   274
    g_pVFrame->pts++;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   275
    if (g_pFormat->flags & AVFMT_RAWPICTURE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   276
    {
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   277
        /* raw video case. The API will change slightly in the near
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   278
           future for that. */
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   279
        Packet.flags |= AV_PKT_FLAG_KEY;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   280
        Packet.stream_index = g_pVStream->index;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   281
        Packet.data = (uint8_t*)pFrame;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   282
        Packet.size = sizeof(AVPicture);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   283
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   284
        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   285
            FatalError("Error while writing video frame");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   286
        return 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   287
    }
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   288
    else
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   289
    {
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   290
#if LIBAVCODEC_VERSION_MAJOR >= 54
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   291
        int got_packet;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   292
        if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   293
            FatalError("avcodec_encode_video2 failed");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   294
        if (!got_packet)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   295
            return 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   296
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   297
        if (Packet.pts != AV_NOPTS_VALUE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   298
            Packet.pts = av_rescale_q(Packet.pts, g_pVideo->time_base, g_pVStream->time_base);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   299
        if (Packet.dts != AV_NOPTS_VALUE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   300
            Packet.dts = av_rescale_q(Packet.dts, g_pVideo->time_base, g_pVStream->time_base);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   301
#else 
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   302
        Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   303
        if (Packet.size < 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   304
            FatalError("avcodec_encode_video failed");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   305
        if (Packet.size == 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   306
            return 0;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   307
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   308
        if( g_pVideo->coded_frame->pts != AV_NOPTS_VALUE)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   309
            Packet.pts = av_rescale_q(g_pVideo->coded_frame->pts, g_pVideo->time_base, g_pVStream->time_base);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   310
        if( g_pVideo->coded_frame->key_frame )
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   311
            Packet.flags |= AV_PKT_FLAG_KEY;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   312
        Packet.data = g_OutBuffer;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   313
#endif
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   314
        // write the compressed frame in the media file
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   315
        Packet.stream_index = g_pVStream->index;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   316
        if (av_interleaved_write_frame(g_pContainer, &Packet) != 0)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   317
            FatalError("Error while writing video frame");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   318
            
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   319
        return 1;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   320
    }
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   321
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   322
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   323
void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   324
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   325
    g_pVFrame->data[0] = pY;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   326
    g_pVFrame->data[1] = pCb;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   327
    g_pVFrame->data[2] = pCr;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   328
    WriteFrame(g_pVFrame);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   329
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   330
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   331
void AVWrapper_Init(
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   332
         void (*pAddFileLogRaw)(const char*),
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   333
         const char* pFilename,
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   334
         const char* pDesc,
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   335
         const char* pSoundFile,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   336
         const char* pFormatName,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   337
         const char* pVCodecName,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   338
         const char* pACodecName,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   339
         const char* pVPreset,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   340
         int Width, int Height,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   341
         int FramerateNum, int FramerateDen,
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   342
         int VQuality, int AQuality)
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   343
{    
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   344
    AddFileLogRaw = pAddFileLogRaw;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   345
    av_log_set_callback( &LogCallback );
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   346
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   347
    g_Width  = Width  & ~1; // make even (dimensions should be even)
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   348
    g_Height = Height & ~1; // make even
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   349
    g_Framerate.num = FramerateNum;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   350
    g_Framerate.den = FramerateDen;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   351
    g_VQuality = VQuality;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   352
    g_AQuality = AQuality;
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   353
    g_pPreset = pVPreset;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   354
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   355
    // initialize libav and register all codecs and formats
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   356
    av_register_all();
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   357
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   358
    // find format
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   359
    g_pFormat = av_guess_format(pFormatName, NULL, NULL);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   360
    if (!g_pFormat)
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   361
        FatalError("Format \"%s\" was not found", pFormatName);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   362
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   363
    // allocate the output media context
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   364
    g_pContainer = avformat_alloc_context();
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   365
    if (!g_pContainer)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   366
        FatalError("Could not allocate output context");
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   367
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   368
    g_pContainer->oformat = g_pFormat;
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   369
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   370
    // store description of file
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   371
    av_dict_set(&g_pContainer->metadata, "comment", pDesc, 0);
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   372
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   373
    // append extesnion to filename
7235
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   374
    char ext[16];
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   375
    strncpy(ext, g_pFormat->extensions, 16);
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   376
    ext[15] = 0;
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   377
    ext[strcspn(ext,",")] = 0;
baa69bd025d9 1. Implement new page in frontend with options for video recording.
Stepan777 <stepik-777@mail.ru>
parents: 7198
diff changeset
   378
    snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   379
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   380
    // find codecs
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   381
    g_pVCodec = avcodec_find_encoder_by_name(pVCodecName);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   382
    g_pACodec = avcodec_find_encoder_by_name(pACodecName);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   383
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   384
    // add audio and video stream to container
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   385
    g_pVStream = NULL;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   386
    g_pAStream = NULL;
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   387
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   388
    if (g_pVCodec)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   389
        AddVideoStream();
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   390
    else
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   391
        Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   392
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   393
    if (g_pACodec)
7280
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   394
    {
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   395
        g_pSoundFile = fopen(pSoundFile, "rb");
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   396
        if (g_pSoundFile)
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   397
        {
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   398
            fread(&g_Frequency, 4, 1, g_pSoundFile);
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   399
            fread(&g_Channels, 4, 1, g_pSoundFile);
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   400
            AddAudioStream();
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   401
        }
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   402
        else
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   403
            Log("Could not open %s", pSoundFile);
fd707afbc3a2 pagevideos is now much better that before:
Stepan777 <stepik-777@mail.ru>
parents: 7235
diff changeset
   404
    }
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   405
    else
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   406
        Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   407
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   408
    if (!g_pAStream && !g_pVStream)
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   409
        FatalError("No video, no audio, aborting...");
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   410
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   411
    // write format info to log
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   412
    av_dump_format(g_pContainer, 0, g_pContainer->filename, 1);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   413
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   414
    // open the output file, if needed
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   415
    if (!(g_pFormat->flags & AVFMT_NOFILE))
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   416
    {
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   417
        if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0)
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   418
            FatalError("Could not open output file (%s)", pFilename);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   419
    }
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   420
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   421
    // write the stream header, if any
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   422
    avformat_write_header(g_pContainer, NULL);
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   423
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   424
    g_pVFrame->pts = -1;
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   425
}
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   426
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   427
void AVWrapper_Close()
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   428
{
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   429
    // output buffered frames
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   430
    if (g_pVCodec->capabilities & CODEC_CAP_DELAY)
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   431
        while( WriteFrame(NULL) );
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   432
    // output any remaining audio
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   433
    while( WriteAudioFrame() );
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   434
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   435
    // write the trailer, if any.
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   436
    av_write_trailer(g_pContainer);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   437
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   438
    // close the output file
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   439
    if (!(g_pFormat->flags & AVFMT_NOFILE))
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   440
        avio_close(g_pContainer->pb);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   441
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   442
    // free everything
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   443
    if (g_pVStream)
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   444
    {
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   445
        avcodec_close(g_pVideo);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   446
        av_free(g_pVideo);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   447
        av_free(g_pVStream);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   448
        av_free(g_pVFrame);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   449
    }
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   450
    if (g_pAStream)
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   451
    {
7198
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   452
        avcodec_close(g_pAudio);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   453
        av_free(g_pAudio);
5debd5fe526e 1. Add IFDEFs for video recording
Stepan777 <stepik-777@mail.ru>
parents: 7180
diff changeset
   454
        av_free(g_pAStream);
7180
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   455
        av_free(g_pAFrame);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   456
        av_free(g_pSamples);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   457
        fclose(g_pSoundFile);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   458
    }
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   459
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   460
    av_free(g_pContainer);
53ffc8853008 here it is
Stepan777 <stepik-777@mail.ru>
parents:
diff changeset
   461
}