4
* This file contains the functions for encoding captured frames on-the-fly
5
* using libavcodec/-format
8
* Copyright (C) 2003-07 Karl H. Beckers, Frankfurt
9
* EMail: khb@jarre-de-the.net
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#ifndef DOXYGEN_SHOULD_SKIP_THIS
30
#endif // HAVE_CONFIG_H
32
#define DEBUGFILE "xtoffmpeg.c"
33
#endif // DOXYGEN_SHOULD_SKIP_THIS
40
#include <sys/types.h>
44
#include <sys/time.h> /* for timeval struct and related
48
#include <X11/Intrinsic.h>
56
#include "xvidcap-intl.h"
59
#include <ffmpeg/avcodec.h>
60
#include <ffmpeg/avformat.h>
61
#include <ffmpeg/avdevice.h>
62
//#include <ffmpeg/dsputil.h>
63
#include <ffmpeg/swscale.h>
64
#include <ffmpeg/rgb2rgb.h>
65
#include <ffmpeg/fifo.h>
66
#define swscale_isRGB(x) ((x)==PIX_FMT_BGR32 || (x)==PIX_FMT_RGB24 \
67
|| (x)==PIX_FMT_RGB565 || (x)==PIX_FMT_RGB555 \
68
|| (x)==PIX_FMT_RGB8 || (x)==PIX_FMT_RGB4 \
69
|| (x)==PIX_FMT_RGB4_BYTE || (x)==PIX_FMT_MONOBLACK)
70
#define swscale_isBGR(x) ((x)==PIX_FMT_RGB32 || (x)==PIX_FMT_BGR24 \
71
|| (x)==PIX_FMT_BGR565 || (x)==PIX_FMT_BGR555 \
72
|| (x)==PIX_FMT_BGR8 || (x)==PIX_FMT_BGR4 \
73
|| (x)==PIX_FMT_BGR4_BYTE || (x)==PIX_FMT_MONOBLACK)
74
#define swscale_isSupportedIn(x) ((x)==PIX_FMT_YUV420P || (x)==PIX_FMT_YUYV422 \
75
|| (x)==PIX_FMT_UYVY422 || (x)==PIX_FMT_RGB32 \
76
|| (x)==PIX_FMT_BGR24 || (x)==PIX_FMT_BGR565 \
77
|| (x)==PIX_FMT_BGR555 || (x)==PIX_FMT_BGR32 \
78
|| (x)==PIX_FMT_RGB24|| (x)==PIX_FMT_RGB565 \
79
|| (x)==PIX_FMT_RGB555 || (x)==PIX_FMT_GRAY8 \
80
|| (x)==PIX_FMT_YUV410P || (x)==PIX_FMT_GRAY16BE \
81
|| (x)==PIX_FMT_GRAY16LE || (x)==PIX_FMT_YUV444P \
82
|| (x)==PIX_FMT_YUV422P || (x)==PIX_FMT_YUV411P \
83
|| (x)==PIX_FMT_PAL8 || (x)==PIX_FMT_BGR8 \
84
|| (x)==PIX_FMT_RGB8 || (x)==PIX_FMT_BGR4_BYTE \
85
|| (x)==PIX_FMT_RGB4_BYTE)
86
// added jpeg stuff myself (yuvj*) because swscale actually DOES
88
#define swscale_isSupportedOut(x) ((x)==PIX_FMT_YUV420P \
89
|| (x)==PIX_FMT_YUYV422 || (x)==PIX_FMT_UYVY422 \
90
|| (x)==PIX_FMT_YUV444P || (x)==PIX_FMT_YUV422P \
91
|| (x)==PIX_FMT_YUV411P || swscale_isRGB(x) \
92
|| swscale_isBGR(x) || (x)==PIX_FMT_NV12 \
93
|| (x)==PIX_FMT_NV21 || (x)==PIX_FMT_GRAY16BE \
94
|| (x)==PIX_FMT_GRAY16LE || (x)==PIX_FMT_GRAY8 \
95
|| (x)==PIX_FMT_YUV410P \
96
|| (x)==PIX_FMT_YUVJ420P || (x)==PIX_FMT_YUVJ422P \
97
|| (x)==PIX_FMT_YUVJ444P)
99
#define PIX_FMT_ARGB32 PIX_FMT_RGBA32 /* this is just my personal
105
/** \brief params for the codecs video */
106
static AVCodec *codec;
108
/** \brief an AVFrame as wrapper around the original image data */
109
static AVFrame *p_inpic;
111
/** \brief and one for the image converted to yuv420p */
112
static AVFrame *p_outpic;
114
/** \brief data buffer for output frame */
115
static uint8_t *outpic_buf;
117
/** \brief output buffer for encoded frame */
118
static uint8_t *outbuf;
120
/** \brief the size of the outbuf may be other than image_size */
121
static int outbuf_size;
123
/** \brief output file via avformat */
124
static AVFormatContext *output_file;
126
/** \brief ... plus related data */
127
static AVOutputFormat *file_oformat;
128
static AVStream *out_st = NULL;
130
/** \brief context for image resampling */
131
static struct SwsContext *img_resample_ctx;
133
/** \brief size of yuv image */
134
static int image_size;
136
/** \brief pix_fmt of original image */
137
static int input_pixfmt;
139
/** \brief store current video_pts for a/v sync */
140
static double video_pts;
142
/** \brief buffer memory used during 8bit palette conversion */
143
static uint8_t *scratchbuf8bit;
145
/** \brief pointer to the XVC_CapTypeOptions representing the currently
146
* active capture mode (which certainly is mf here) */
147
static XVC_CapTypeOptions *target = NULL;
150
static void dump8bit (const XImage * image, const u_int32_t * ct);
151
static void dump32bit (const XImage * input, const ColorInfo * c_info);
153
/** \todo: what about const-correctness for the next line */
154
static void x2ffmpeg_dump_ximage_info (XImage * img, FILE * fp);
157
#ifdef HAVE_FFMPEG_AUDIO
159
#define MAX_AUDIO_PACKET_SIZE (128 * 1024)
165
* \brief AVOutputStream taken from ffmpeg.c
167
typedef struct AVOutputStream
169
int file_index; /* file index */
170
int index; /* stream index in the output file */
171
int source_index; /* AVInputStream index */
172
AVStream *st; /* stream in the output file */
173
int encoding_needed; /* true if encoding needed for this stream */
175
/* input pts and corresponding output pts for A/V sync */
176
struct AVInputStream *sync_ist; /* input stream to sync against */
177
int64_t sync_opts; /* output frame counter, could be changed
178
* to some true timestamp */
181
AVFrame pict_tmp; /* temporary image for resampling */
182
struct SwsContext *img_resample_ctx; /* for image resampling */
186
int topBand; /* cropping area sizes */
190
int padtop; /* padding area sizes */
197
ReSampleContext *resample; /* for audio resampling */
198
AVFifoBuffer fifo; /* for compression: one audio fifo per
203
typedef struct AVInputStream
208
int discard; /* true if stream data should be discarded
210
int decoding_needed; /* true if the packets must be decoded in
212
int64_t sample_index; /* current sample */
214
int64_t start; /* time when read started */
215
unsigned long frame; /* current frame */
216
int64_t next_pts; /* synthetic pts for cases where pkt.pts
218
int64_t pts; /* current pts */
219
int is_start; /* is 1 at the start and after a
223
// FIXME: check if this all needs to be static global
224
/** \brief audio codec */
225
static AVCodec *au_codec = NULL;
227
/** \brief audio codec context */
228
static AVCodecContext *au_c = NULL;
230
/** \brief format context for audio input */
231
static AVFormatContext *ic = NULL;
233
/** \brief audio output stream */
234
static AVOutputStream *au_out_st = NULL;
236
/** \brief audio input stream */
237
static AVInputStream *au_in_st = NULL;
239
/** \brief buffer used during audio capture */
240
static uint8_t *audio_buf = NULL;
242
/** \brief buffer used during audio encoding */
243
static uint8_t *audio_out = NULL;
245
/** \brief thread coordination variables for interleaving audio and video
246
* capture. This is the thread's attributes */
247
static pthread_attr_t tattr;
249
/** \brief thread coordination variables for interleaving audio and video
250
* capture. This is the mutex lock */
251
static pthread_mutex_t mp = PTHREAD_MUTEX_INITIALIZER;
253
/** \brief thread coordination variables for interleaving audio and video
254
* capture. This is the thread's id */
255
static pthread_t tid = 0;
257
static int audio_thread_running = FALSE;
259
/** \brief store current audio_pts for a/v sync */
260
static double audio_pts;
268
* \brief adds an audio stream to AVFormatContext output_file
270
* @param job the current job
271
* @return 0 on success or smth. else on failure
274
add_audio_stream (Job * job)
276
#define DEBUGFUNCTION "add_audio_stream()"
277
AVInputFormat *grab_iformat = NULL;
278
Boolean grab_audio = TRUE;
279
AVFormatParameters params, *ap = ¶ms; // audio stream params
283
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
286
if (!strcmp (job->snd_device, "-")) {
287
job->snd_device = "pipe:";
293
// prepare input stream
294
memset (ap, 0, sizeof (*ap));
295
// ap->device = job->snd_device;
298
ap->sample_rate = target->sndrate;
299
ap->channels = target->sndchannels;
301
grab_iformat = av_find_input_format ("oss");
303
printf ("%s %s: grab iformat %p\n", DEBUGFILE, DEBUGFUNCTION,
306
printf ("%s %s: grab iformat name %s\n", DEBUGFILE,
307
DEBUGFUNCTION, grab_iformat->name);
312
av_open_input_file (&ic, job->snd_device,
313
(grab_audio ? grab_iformat : NULL), 0, ap);
315
fprintf (stderr, _("%s %s: error opening input file %s: %i\n"),
316
DEBUGFILE, DEBUGFUNCTION, job->snd_device, err);
319
au_in_st = av_mallocz (sizeof (AVInputStream));
320
if (!au_in_st || !ic) {
322
_("%s %s: Could not alloc input stream ... aborting\n"),
323
DEBUGFILE, DEBUGFUNCTION);
326
au_in_st->st = ic->streams[0];
328
// If not enough info to get the stream parameters, we decode
329
// the first frames to get it. (used in mpeg case for example)
330
ret = av_find_stream_info (ic);
332
fprintf (stderr, _("%s %s: could not find codec parameters\n"),
333
DEBUGFILE, DEBUGFUNCTION);
341
au_in_st->next_pts = 0;
342
au_in_st->is_start = 1;
345
dump_format (ic, 0, job->snd_device, 0);
349
// setup output codec
350
au_c = avcodec_alloc_context ();
354
("%s %s: could not allocate audio output codec context\n"),
355
DEBUGFILE, DEBUGFUNCTION);
362
// put sample parameters
363
au_c->codec_id = xvc_audio_codecs[job->au_targetCodec].ffmpeg_id;
364
au_c->codec_type = CODEC_TYPE_AUDIO;
365
au_c->bit_rate = target->sndsize;
366
au_c->sample_rate = target->sndrate;
367
au_c->channels = target->sndchannels;
368
// au_c->debug = 0x00000FFF;
370
// prepare output stream
371
au_out_st = av_mallocz (sizeof (AVOutputStream));
374
_("%s %s: Could not alloc stream ... aborting\n"),
375
DEBUGFILE, DEBUGFUNCTION);
382
au_out_st->st = av_new_stream (output_file, 1);
383
if (!au_out_st->st) {
384
fprintf (stderr, _("%s %s: Could not alloc stream\n"),
385
DEBUGFILE, DEBUGFUNCTION);
392
au_out_st->st->codec = au_c;
394
if (av_fifo_init (&au_out_st->fifo, 2 * MAX_AUDIO_PACKET_SIZE)) {
396
_("%s %s: Can't initialize fifo for audio recording\n"),
397
DEBUGFILE, DEBUGFUNCTION);
404
// This bit is important for inputs other than self-sampled.
405
// The sample rates and no of channels a user asks for
406
// are the ones he/she wants in the encoded mpeg. For self-
407
// sampled audio, these are also the values used for sampling.
408
// Hence there is no resampling necessary (case 1).
409
// When dubbing from a pipe or a different
410
// file, we might have different sample rates or no of
412
// in the input file.....
413
if (au_c->channels == au_in_st->st->codec->channels &&
414
au_c->sample_rate == au_in_st->st->codec->sample_rate) {
415
au_out_st->audio_resample = 0;
417
if (au_c->channels != au_in_st->st->codec->channels &&
418
au_in_st->st->codec->codec_id == CODEC_ID_AC3) {
419
// Special case for 5:1 AC3 input
420
// and mono or stereo output
421
// Request specific number of channels
422
au_in_st->st->codec->channels = au_c->channels;
423
if (au_c->sample_rate == au_in_st->st->codec->sample_rate)
424
au_out_st->audio_resample = 0;
426
au_out_st->audio_resample = 1;
427
au_out_st->resample =
428
audio_resample_init (au_c->channels,
429
au_in_st->st->codec->
432
au_in_st->st->codec->sample_rate);
433
if (!au_out_st->resample) {
434
printf (_("%s %s: Can't resample. Aborting.\n"),
435
DEBUGFILE, DEBUGFUNCTION);
443
// Request specific number of channels
444
au_in_st->st->codec->channels = au_c->channels;
446
au_out_st->audio_resample = 1;
447
au_out_st->resample =
448
audio_resample_init (au_c->channels,
449
au_in_st->st->codec->channels,
451
au_in_st->st->codec->sample_rate);
452
if (!au_out_st->resample) {
453
printf (_("%s %s: Can't resample. Aborting.\n"), DEBUGFILE,
463
au_in_st->decoding_needed = 1;
464
au_out_st->encoding_needed = 1;
467
au_codec = avcodec_find_encoder (au_out_st->st->codec->codec_id);
468
if (avcodec_open (au_out_st->st->codec, au_codec) < 0) {
470
_("%s %s: Error while opening codec for output stream\n"),
471
DEBUGFILE, DEBUGFUNCTION);
479
au_codec = avcodec_find_decoder (ic->streams[0]->codec->codec_id);
482
_("%s %s: Unsupported codec (id=%d) for input stream\n"),
483
DEBUGFILE, DEBUGFUNCTION, ic->streams[0]->codec->codec_id);
490
if (avcodec_open (ic->streams[0]->codec, au_codec) < 0) {
492
_("%s %s: Error while opening codec for input stream\n"),
493
DEBUGFILE, DEBUGFUNCTION);
501
printf ("%s %s: Leaving with %i streams in oc\n", DEBUGFILE,
502
DEBUGFUNCTION, output_file->nb_streams);
509
* \brief encode and write audio samples
511
* @param s output format context (output_file)
512
* @param ost pointer to audio output stream
513
* @param ist input stream information
514
* @param buf the actual data sampled
515
* @param size the size of the data sampled
518
do_audio_out (AVFormatContext * s, AVOutputStream * ost,
519
const AVInputStream * ist, unsigned char *buf, int size)
521
#define DEBUGFUNCTION "do_audio_out()"
523
const int audio_out_size = 4 * MAX_AUDIO_PACKET_SIZE;
524
int size_out, frame_bytes;
527
// SC: dynamic allocation of buffers
529
audio_buf = av_malloc (2 * MAX_AUDIO_PACKET_SIZE);
531
audio_out = av_malloc (audio_out_size);
532
if (!audio_out || !audio_buf)
533
return; // Should signal an error !
535
enc = ost->st->codec;
537
// resampling is only used for pipe input here
538
if (ost->audio_resample) {
541
audio_resample (ost->resample, (short *) buftmp, (short *) buf,
542
size / (ist->st->codec->channels * 2));
543
size_out = size_out * enc->channels * 2;
549
// now encode as many frames as possible
550
if (enc->frame_size > 1) {
551
// output resampled raw samples
552
av_fifo_write (&ost->fifo, buftmp, size_out);
553
frame_bytes = enc->frame_size * 2 * enc->channels;
555
while (av_fifo_read (&ost->fifo, audio_buf, frame_bytes) == 0) {
558
// initialize audio output packet
559
av_init_packet (&pkt);
562
avcodec_encode_audio (enc, audio_out, size_out,
563
(short *) audio_buf);
565
if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE) {
567
av_rescale_q (enc->coded_frame->pts, enc->time_base,
570
pkt.flags |= PKT_FLAG_KEY;
571
pkt.stream_index = ost->st->index;
573
pkt.data = audio_out;
574
if (pthread_mutex_trylock (&mp) == 0) {
575
// write the compressed frame in the media file
576
if (av_interleaved_write_frame (s, &pkt) != 0) {
578
_("%s %s: Error while writing audio frame\n"),
579
DEBUGFILE, DEBUGFUNCTION);
584
if (pthread_mutex_unlock (&mp) > 0) {
587
("%s %s: Couldn't unlock mutex lock for writing audio frame\n"),
588
DEBUGFILE, DEBUGFUNCTION);
595
av_init_packet (&pkt);
597
/* output a pcm frame */
598
/* XXX: change encoding codec API to avoid this ? */
599
switch (enc->codec->id) {
600
case CODEC_ID_PCM_S32LE:
601
case CODEC_ID_PCM_S32BE:
602
case CODEC_ID_PCM_U32LE:
603
case CODEC_ID_PCM_U32BE:
604
size_out = size_out << 1;
606
case CODEC_ID_PCM_S24LE:
607
case CODEC_ID_PCM_S24BE:
608
case CODEC_ID_PCM_U24LE:
609
case CODEC_ID_PCM_U24BE:
610
case CODEC_ID_PCM_S24DAUD:
611
size_out = size_out / 2 * 3;
613
case CODEC_ID_PCM_S16LE:
614
case CODEC_ID_PCM_S16BE:
615
case CODEC_ID_PCM_U16LE:
616
case CODEC_ID_PCM_U16BE:
619
size_out = size_out >> 1;
623
avcodec_encode_audio (enc, audio_out, size_out, (short *) buftmp);
624
pkt.stream_index = ost->st->index;
625
pkt.data = audio_out;
626
if (enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)
628
av_rescale_q (enc->coded_frame->pts, enc->time_base,
630
pkt.flags |= PKT_FLAG_KEY;
631
av_interleaved_write_frame (s, &pkt);
638
* \brief signal handler for stopping the audio capture thread which
639
* runs till sent a SIGUSR1 signal
642
cleanup_thread_when_stopped ()
644
#define DEBUGFUNCTION "cleanup_thread_when_stopped()"
649
int bit_buffer_size = 1024 * 256;
650
uint8_t *bit_buffer = NULL;
651
short *samples = NULL;
654
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
657
av_init_packet (&pkt);
658
// pkt.stream_index= ost->index;
660
enc = au_out_st->st->codec;
661
samples = av_malloc (AVCODEC_MAX_AUDIO_FRAME_SIZE);
662
bit_buffer = av_malloc (bit_buffer_size);
663
fifo_bytes = av_fifo_size (&au_out_st->fifo);
666
/* encode any samples remaining in fifo */
667
if (fifo_bytes > 0 &&
668
enc->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME &&
669
bit_buffer && samples) {
670
int fs_tmp = enc->frame_size;
672
enc->frame_size = fifo_bytes / (2 * enc->channels);
673
if (av_fifo_read (&au_out_st->fifo, (uint8_t *) samples, fifo_bytes) ==
676
avcodec_encode_audio (enc, bit_buffer, bit_buffer_size,
679
enc->frame_size = fs_tmp;
682
ret = avcodec_encode_audio (enc, bit_buffer, bit_buffer_size, NULL);
684
pkt.flags |= PKT_FLAG_KEY;
691
av_free (bit_buffer);
707
av_close_input_file (ic);
710
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
713
audio_thread_running = FALSE;
719
* \brief this function implements the thread doing the audio capture and
720
* interleaving the captured audio frames with the video output
722
* @param job the current job
725
capture_audio_thread (Job * job)
727
#define DEBUGFUNCTION "capture_audio_thread()"
728
XVC_AppData *app = xvc_appdata_ptr ();
729
unsigned long start, stop, start_s, stop_s;
730
struct timeval thr_curr_time;
732
int ret, len, data_size;
733
uint8_t *ptr, *data_buf;
734
static unsigned int samples_size = 0;
735
static short *samples = NULL;
738
audio_thread_running = TRUE;
739
signal (SIGUSR1, cleanup_thread_when_stopped);
743
gettimeofday (&thr_curr_time, NULL);
744
start_s = thr_curr_time.tv_sec;
745
start = thr_curr_time.tv_usec;
747
if ((job->state & VC_PAUSE) && !(job->state & VC_STEP)) {
748
pthread_mutex_lock (&(app->recording_paused_mutex));
749
pthread_cond_wait (&(app->recording_condition_unpaused),
750
&(app->recording_paused_mutex));
751
pthread_mutex_unlock (&(app->recording_paused_mutex));
752
} else if (job->state == VC_REC) {
755
au_out_st->st->pts.val *
756
au_out_st->st->time_base.num / au_out_st->st->time_base.den;
758
(double) out_st->pts.val * out_st->time_base.num /
759
out_st->time_base.den;
761
// sometimes we need to pause writing audio packets for a/v
762
// sync (when audio_pts >= video_pts)
763
// now, if we're reading from a file/pipe, we stop sampling or
764
// else the audio track in the video would become choppy (packets
765
// missing where they were read but not written)
766
// for real-time sampling we can't do that because otherwise
767
// the input packets queue up and will eventually be sampled
768
// (only later) and lead to out-of-sync audio (video faster)
769
if (audio_pts < video_pts) {
770
// read a packet from it and output it in the fifo
771
if (av_read_frame (ic, &pkt) < 0) {
773
_("%s %s: error reading audio packet\n"),
774
DEBUGFILE, DEBUGFUNCTION);
779
// decode the packet if needed
780
data_buf = NULL; /* fail safe */
783
if (au_in_st->decoding_needed) {
784
samples = av_fast_realloc (samples, &samples_size,
786
AVCODEC_MAX_AUDIO_FRAME_SIZE));
787
data_size = samples_size;
788
/* XXX: could avoid copy if PCM 16 bits with same
789
* endianness as CPU */
791
avcodec_decode_audio2 (au_in_st->st->codec, samples,
792
&data_size, ptr, len);
796
("%s %s: couldn't decode captured audio packet\n"),
797
DEBUGFILE, DEBUGFUNCTION);
802
/* Some bug in mpeg audio decoder gives */
803
/* data_size < 0, it seems they are overflows */
804
if (data_size <= 0) {
807
fprintf (stderr, _("%s %s: no audio frame\n"),
808
DEBUGFILE, DEBUGFUNCTION);
812
data_buf = (uint8_t *) samples;
813
au_in_st->next_pts +=
814
((int64_t) AV_TIME_BASE / 2 * data_size) /
815
(au_in_st->st->codec->sample_rate *
816
au_in_st->st->codec->channels);
818
// FIXME: dunno about the following
819
au_in_st->next_pts +=
820
((int64_t) AV_TIME_BASE *
821
au_in_st->st->codec->frame_size) /
822
(au_in_st->st->codec->sample_rate *
823
au_in_st->st->codec->channels);
830
do_audio_out (output_file, au_out_st, au_in_st,
831
data_buf, data_size);
834
av_free_packet (&pkt);
835
} // end outside if pts ...
837
if (strcmp (job->snd_device, "pipe:") < 0)
838
if (av_read_frame (ic, &pkt) < 0) {
839
fprintf (stderr, _("error reading audio packet\n"));
842
printf (_("%s %s: dropping audio frame %f %f\n"),
843
DEBUGFILE, DEBUGFUNCTION, audio_pts, video_pts);
848
gettimeofday (&thr_curr_time, NULL);
849
stop_s = thr_curr_time.tv_sec;
850
stop = thr_curr_time.tv_usec;
851
stop += ((stop_s - start_s) * 1000000);
852
sleep = (1000000 / target->sndrate) - (stop - start);
854
* \todo perhaps this whole stuff is irrelevant. Haven't really
855
* seen a situation where the encoding was faster than the time
856
* needed for a decent frame-rate. need to look into more
857
* details about audio/video sync in libavcodec/-format
858
* the strange thing, however is: If I leave away the getting of
859
* start/end time and the usleep stuff, normal audio capture
860
* works, piped audio doesn't *BLINK*
866
} // end while(TRUE) loop
868
audio_thread_running = FALSE;
873
#endif // HAVE_FFMPEG_AUDIO
876
* \brief write encoded video data
878
* @param s pointer to format context (output_file)
879
* @param ost video output stream
880
* @param buf buffer with actual data
881
* @param size size of encoded data
884
do_video_out (AVFormatContext * s, AVStream * ost, unsigned char *buf, int size)
886
#define DEBUGFUNCTION "do_video_out()"
892
("%s %s: Entering with format context %p output stream %p buffer %p size %i\n",
893
DEBUGFILE, DEBUGFUNCTION, s, ost, buf, size);
898
// initialize video output packet
899
av_init_packet (&pkt);
901
if (enc->coded_frame) {
902
if (enc->coded_frame->pts != AV_NOPTS_VALUE) {
904
av_rescale_q (enc->coded_frame->pts, enc->time_base,
907
if (enc->coded_frame->key_frame)
908
pkt.flags |= PKT_FLAG_KEY;
911
pkt.stream_index = ost->index;
915
if (av_interleaved_write_frame (s, &pkt) != 0) {
916
fprintf (stderr, _("%s %s: Error while writing video frame\n"),
917
DEBUGFILE, DEBUGFUNCTION);
922
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
929
* \brief convert bgra32 to rgba32
931
* needed on Solaris/SPARC because the ffmpeg version used doesn't know
932
* PIX_FMT_ABGR32, i.e. byte ordering is not taken care of
933
* @param image the XImage to convert
936
myABGR32toARGB32 (XImage * image)
938
#define DEBUGFUNCTION "myABGR32toARGB32()"
939
char *pdata, *counter;
942
printf ("%s %s: Entering with image %p\n", DEBUGFILE, DEBUGFUNCTION, image);
947
for (counter = pdata;
948
counter < (pdata + (image->width * image->height * 4)); counter += 4) {
951
if (image->byte_order) { // MSBFirst has order argb -> abgr
953
swap = *(counter + 1);
954
*(counter + 1) = *(counter + 3);
955
*(counter + 3) = swap;
956
} else { // LSBFirst has order bgra -> rgba
958
*counter = *(counter + 2);
959
*(counter + 2) = swap;
964
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
971
* \brief convert pal8 to rgba32
973
* libswscale does not support pal8 input atm
974
* @param image the XImage to convert
975
* @param p_inpic pointer to a frame to where the converted output is written
976
* @param job the current job
977
* \todo very current ffmpeg versions seem to make this unneccessary
980
myPAL8toRGB24 (XImage * image, AVFrame * p_inpic, Job * job)
982
#define DEBUGFUNCTION "myABGR32toRGB24()"
984
u_int32_t *color_table = job->color_table;
986
uint8_t *out_cursor = NULL;
987
uint8_t *out = (uint8_t *) p_inpic->data[0];
990
* 8bit pseudo-color images may have lines padded by excess bytes
991
* these need to be removed before conversion
992
* \todo other formats might also have this problem
994
for (y = 0; y < image->height; y++) {
995
out_cursor = (uint8_t *) image->data + (y * image->bytes_per_line);
996
for (x = 0; x < image->width; x++) {
997
*out++ = ((color_table[*out_cursor] & 0x00FF0000) >> 16);
998
*out++ = ((color_table[*out_cursor] & 0x0000FF00) >> 8);
999
*out++ = (color_table[*out_cursor] & 0x000000FF);
1004
#undef DEBUGFUNCTION
1008
* \brief prepare the color table for pseudo color input to libavcodec's
1011
* I'm downsampling the 16 bit color entries to 8 bit as it expects
1012
* 32 bit (=4 * 8) from looking at imgconvert_template.c I'd say libavcodec
1013
* expects argb logically, not byte-wise
1014
* @param colors a pointer to the colors as contained in the captured XImage
1015
* @param ncolors the number of colors present
1016
* @return a pointer to the converted color table
1019
xvc_ffmpeg_get_color_table (XColor * colors, int ncolors)
1021
#define DEBUGFUNCTION "xvc_ffmpeg_get_color_table()"
1022
u_int32_t *color_table, *pixel;
1026
printf ("%s %s: Entering with colors %p and %i colors\n",
1027
DEBUGFILE, DEBUGFUNCTION, colors, ncolors);
1030
color_table = malloc (256 * 4);
1034
pixel = color_table;
1035
for (i = 0; i < ncolors; i++) {
1036
u_int32_t color_table_entry, swap;
1038
color_table_entry = 0;
1041
swap = colors[i].red;
1042
swap &= 0x0000FF00; // color is 16 bits, delete ls 8 bits
1043
swap <<= 8; // then shift ms 8 bits into position
1044
color_table_entry = (color_table_entry | swap);
1046
swap = colors[i].green;
1047
swap &= 0x0000FF00; /* color is 16 bits, ms 8 bits already
1048
* in position, delete ls 8 bits */
1049
color_table_entry = (color_table_entry | swap);
1051
swap = colors[i].blue;
1053
color_table_entry = (color_table_entry | swap);
1055
*pixel = color_table_entry;
1059
printf ("%s %s: color_table pointer: %p\n",
1060
DEBUGFILE, DEBUGFUNCTION, color_table);
1061
printf ("%s %s: color_table third entry: 0x%.8X\n",
1062
DEBUGFILE, DEBUGFUNCTION, *(color_table + 2));
1063
// first and second black & white
1067
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1071
#undef DEBUGFUNCTION
1075
* \brief prepare the output file or pipe
1077
* need to determine which first and do things like making the filename
1079
* @param jFileName the filename as contained in the current job
1080
* @param oc output format context (output_file)
1081
* @param number the movie number
1084
prepareOutputFile (char *jFileName, AVFormatContext * oc, int number)
1086
#define DEBUGFUNCTION "prepareOutputFile()"
1090
("%s %s: Entering with filename %s format context %p and number %i\n",
1091
DEBUGFILE, DEBUGFUNCTION, jFileName, oc, number);
1094
// prepare output file for format context
1096
if ((strcasecmp (jFileName, "-") == 0)
1097
|| (strcasecmp (jFileName, "pipe:") == 0)) {
1098
jFileName = "pipe:";
1099
snprintf (oc->filename, sizeof (oc->filename), "pipe:");
1100
// register_protocol (&pipe_protocol);
1103
char tmp_buf[PATH_MAX + 1];
1105
first = jFileName[0];
1106
sprintf (tmp_buf, jFileName, number);
1108
// if the filename's first char is a / we have an absolute path
1109
// and we want one for the file URL. If we don't have one, we
1112
sprintf (oc->filename, "file://%s/%s", getenv ("PWD"), tmp_buf);
1114
sprintf (oc->filename, "file://%s", tmp_buf);
1116
// register_protocol (&file_protocol);
1120
printf ("%s %s: Leaving with filename %s\n", DEBUGFILE, DEBUGFUNCTION,
1124
#undef DEBUGFUNCTION
1128
* \brief add a video output stream to the output format
1130
* @param oc output format context (output_file)
1131
* @param image captured XImage
1132
* @param input_pixfmt picture format of the input picture
1133
* @param codec_id libavcodec's codec id of the codec to use for encoding
1134
* @param job pointer to the current job
1135
* @return pointer to the AVStream that has been added to the output format
1138
add_video_stream (AVFormatContext * oc, const XImage * image,
1139
int input_pixfmt, int codec_id, Job * job)
1141
#define DEBUGFUNCTION "add_video_stream()"
1143
int pix_fmt_mask = 0, i = 0;
1144
int quality = target->quality, qscale = 0;
1145
XVC_AppData *app = xvc_appdata_ptr ();
1148
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1151
st = av_new_stream (oc, 0);
1154
_("%s %s: Could not alloc output stream\n"), DEBUGFILE,
1159
st->codec->codec_id = codec_id;
1160
st->codec->codec_type = CODEC_TYPE_VIDEO;
1162
// find the video encoder
1163
codec = avcodec_find_encoder (st->codec->codec_id);
1165
fprintf (stderr, _("%s %s: video codec not found\n"),
1166
DEBUGFILE, DEBUGFUNCTION);
1169
// put sample parameters
1170
// resolution must be a multiple of two ... this is taken care of
1171
// elsewhere but needs to be ensured for rescaled dimensions, too
1172
if (app->rescale != 100) {
1176
r = sqrt ((double) app->rescale / 100.0);
1178
n = image->width * r;
1181
st->codec->width = n;
1183
n = image->height * r;
1186
st->codec->height = n;
1188
st->codec->width = image->width;
1189
st->codec->height = image->height;
1193
if (codec_id == CODEC_ID_MPEG4 || codec_id == CODEC_ID_MPEG1VIDEO ||
1194
codec_id == CODEC_ID_MPEG2VIDEO) {
1195
// the max threads is taken from ffmpeg's mpegvideo.c
1196
avcodec_thread_init (st->codec, XVC_MIN (4,
1197
(st->codec->height +
1200
// time base: this is the fundamental unit of time (in seconds) in
1201
// terms of which frame timestamps are represented. for fixed-fps
1202
// content, timebase should be 1/framerate and timestamp increments
1203
// should be identically 1.
1204
st->codec->time_base.den = target->fps.num;
1205
st->codec->time_base.num = target->fps.den;
1206
// emit one intra frame every fifty frames at most
1207
st->codec->gop_size = 50;
1208
st->codec->mb_decision = 2;
1209
st->codec->me_method = 1;
1211
// find suitable pix_fmt for codec
1212
st->codec->pix_fmt = -1;
1213
if (codec->pix_fmts != NULL) {
1214
for (i = 0; codec->pix_fmts[i] != -1; i++) {
1215
if (0 <= codec->pix_fmts[i] &&
1216
codec->pix_fmts[i] < (sizeof (int) * 8))
1217
pix_fmt_mask |= (1 << codec->pix_fmts[i]);
1219
st->codec->pix_fmt =
1220
avcodec_find_best_pix_fmt (pix_fmt_mask, input_pixfmt, FALSE, NULL);
1224
("%s %s: pix_fmt_mask %i, has alpha %i, input_pixfmt %i, output pixfmt %i\n",
1225
DEBUGFILE, DEBUGFUNCTION, pix_fmt_mask,
1226
FALSE, input_pixfmt, st->codec->pix_fmt);
1229
if (!swscale_isSupportedIn (input_pixfmt)) {
1232
("%s %s: The picture format you are grabbing (%i) is not supported by libswscale ... aborting\n"),
1233
DEBUGFILE, DEBUGFUNCTION, input_pixfmt);
1236
if (!swscale_isSupportedOut (st->codec->pix_fmt)) {
1237
st->codec->pix_fmt = -1;
1239
// fallback pix fmts
1240
if (st->codec->pix_fmt < 0) {
1241
if (job->target >= CAP_MF) {
1242
st->codec->pix_fmt = PIX_FMT_YUV420P;
1244
st->codec->pix_fmt = PIX_FMT_RGB24;
1248
st->codec->flags |= CODEC_FLAG2_FAST;
1249
// there is no trellis quantiser in libav* for mjpeg
1250
if (st->codec->codec_id != CODEC_ID_MJPEG)
1251
st->codec->flags |= CODEC_FLAG_TRELLIS_QUANT;
1252
st->codec->flags &= ~CODEC_FLAG_OBMC;
1253
// some formats want stream headers to be seperate
1254
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
1255
st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
1257
// quality through VBR
1258
st->codec->flags |= CODEC_FLAG_QSCALE;
1259
qscale = (100.0 - quality + 1.0) / 3.3;
1260
st->codec->global_quality = st->quality = FF_QP2LAMBDA * qscale;
1261
// 0.0 = default qscale
1263
st->codec->qmin = st->codec->qmax = qscale;
1266
printf ("%s %s: Leaving with %i streams in oc, bitrate %i, and qscale %i\n",
1267
DEBUGFILE, DEBUGFUNCTION, oc->nb_streams, st->codec->bit_rate,
1272
#undef DEBUGFUNCTION
1276
* \brief guess the picture format of the captured image
1278
* @param image captured XImage
1279
* @param c_info needed for alpha channel info
1280
* @return libavcodec's picture format
1283
guess_input_pix_fmt (const XImage * image, const ColorInfo * c_info)
1285
#define DEBUGFUNCTION "guess_input_pix_fmt()"
1288
switch (image->bits_per_pixel) {
1291
printf ("%s %s: 8 bit pallete\n", DEBUGFILE, DEBUGFUNCTION);
1293
input_pixfmt = PIX_FMT_PAL8;
1296
if (image->red_mask == 0xF800 && image->green_mask == 0x07E0
1297
&& image->blue_mask == 0x1F) {
1299
printf ("%s %s: 16 bit RGB565\n", DEBUGFILE, DEBUGFUNCTION);
1301
input_pixfmt = PIX_FMT_BGR565;
1302
} else if (image->red_mask == 0x7C00
1303
&& image->green_mask == 0x03E0 && image->blue_mask == 0x1F) {
1305
printf ("%s %s: 16 bit RGB555\n", DEBUGFILE, DEBUGFUNCTION);
1307
input_pixfmt = PIX_FMT_BGR555;
1312
("%s %s: rgb ordering at image depth %i not supported ... aborting\n"),
1313
DEBUGFILE, DEBUGFUNCTION, image->bits_per_pixel);
1315
"%s %s: color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n",
1316
DEBUGFILE, DEBUGFUNCTION, image->red_mask,
1317
image->green_mask, image->blue_mask);
1322
if (image->red_mask == 0xFF0000 && image->green_mask == 0xFF00
1323
&& image->blue_mask == 0xFF) {
1324
input_pixfmt = PIX_FMT_BGR24;
1325
} else if (image->red_mask == 0xFF
1326
&& image->green_mask == 0xFF00
1327
&& image->blue_mask == 0xFF0000) {
1328
input_pixfmt = PIX_FMT_RGB24;
1332
("%s %s: rgb ordering at image depth %i not supported ... aborting\n"),
1333
DEBUGFILE, DEBUGFUNCTION, image->bits_per_pixel);
1335
"%s %s: color masks: r 0x%.6lX g 0x%.6lX b 0x%.6lX\n",
1336
DEBUGFILE, DEBUGFUNCTION, image->red_mask,
1337
image->green_mask, image->blue_mask);
1342
if (c_info->alpha_mask == 0xFF000000 && image->green_mask == 0xFF00) {
1343
// byte order is relevant here, not endianness endianness is
1344
// handled by avcodec, but atm no such thing as having ABGR,
1345
// instead of ARGB in a word. Since we need this for
1346
// Solaris/SPARC, but need to do the conversion
1347
// for every frame we do it outside of this loop, cf.
1348
// below this matches both ARGB32 and ABGR32
1349
input_pixfmt = PIX_FMT_ARGB32;
1353
("%s %s: image depth %i not supported ... aborting\n"),
1354
DEBUGFILE, DEBUGFUNCTION, image->bits_per_pixel);
1360
_("%s %s: image depth %i not supported ... aborting\n"),
1361
DEBUGFILE, DEBUGFUNCTION, image->bits_per_pixel);
1365
return input_pixfmt;
1366
#undef DEBUGFUNCTION
1370
* \brief main function to write ximage as video to 'fp'
1372
* @param fp file handle, this, however, is not really used with xtoffmpeg
1373
* @param image the captured XImage to save
1374
* \todo remove fp from outside the save function. It is only needed in
1375
* xwd and should reside there
1378
xvc_ffmpeg_save_frame (FILE * fp, XImage * image)
1380
#define DEBUGFUNCTION "xvc_ffmpeg_save_frame()"
1381
Job *job = xvc_job_ptr ();
1382
XVC_AppData *app = xvc_appdata_ptr ();
1384
/* size of the encoded frame to write to file */
1388
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1391
// encoder needs to be prepared only once ..
1392
if (job->state & VC_START) { // it's the first call
1395
printf ("%s %s: doing x2ffmpeg init for targetCodec %i\n",
1396
DEBUGFILE, DEBUGFUNCTION, job->targetCodec);
1400
if (app->current_mode > 0)
1401
target = &(app->multi_frame);
1403
#endif // USE_FFMPEG
1404
target = &(app->single_frame);
1410
printf ("%s %s: got color info\n", DEBUGFILE, DEBUGFUNCTION);
1411
errout = fdopen (2, "w");
1412
// x2ffmpeg_dump_ximage_info(image, errout);
1413
printf ("%s %s: alpha_mask: 0x%.8X\n",
1414
DEBUGFILE, DEBUGFUNCTION, job->c_info->alpha_mask);
1415
printf ("%s %s: alpha_shift: %li\n",
1416
DEBUGFILE, DEBUGFUNCTION, job->c_info->alpha_shift);
1417
printf ("%s %s: red_shift: %li\n",
1418
DEBUGFILE, DEBUGFUNCTION, job->c_info->red_shift);
1419
printf ("%s %s: green_shift: %li\n",
1420
DEBUGFILE, DEBUGFUNCTION, job->c_info->green_shift);
1421
printf ("%s %s: blue_shift: %li\n",
1422
DEBUGFILE, DEBUGFUNCTION, job->c_info->blue_shift);
1427
printf ("%s %s: image->byte_order: %i, msb=%i, lsb=%i\n",
1428
DEBUGFILE, DEBUGFUNCTION, image->byte_order, MSBFirst,
1432
// determine input picture format
1433
input_pixfmt = guess_input_pix_fmt (image, job->c_info);
1435
// register all libav* related stuff
1436
avdevice_register_all ();
1439
// guess AVOutputFormat
1440
if (job->target >= CAP_MF)
1442
guess_format (xvc_formats[job->target].ffmpeg_name, NULL, NULL);
1446
snprintf (tmp_fn, 29, "test-%%d.%s",
1447
xvc_formats[job->target].extensions[0]);
1448
file_oformat = guess_format (NULL, tmp_fn, NULL);
1450
if (!file_oformat) {
1453
("%s %s: Couldn't determin output format ... aborting\n"),
1454
DEBUGFILE, DEBUGFUNCTION);
1459
("%s %s: found AVOutputFormat %s it expects a number in the filename (0=no/1=yes) %i\n",
1460
DEBUGFILE, DEBUGFUNCTION, file_oformat->name,
1461
(file_oformat->flags & AVFMT_NEEDNUMBER));
1463
("%s %s: found based on: target %i - targetCodec %i - ffmpeg codec id %i\n",
1464
DEBUGFILE, DEBUGFUNCTION, job->target, job->targetCodec,
1465
xvc_codecs[job->targetCodec].ffmpeg_id);
1468
// prepare AVFormatContext
1469
output_file = av_alloc_format_context ();
1473
("%s %s: Error allocating memory for format context ... aborting\n"),
1474
DEBUGFILE, DEBUGFUNCTION);
1477
output_file->oformat = file_oformat;
1478
if (output_file->oformat->priv_data_size > 0) {
1479
output_file->priv_data =
1480
av_mallocz (output_file->oformat->priv_data_size);
1481
// FIXME: do I need to free this?
1482
if (!output_file->priv_data) {
1485
("%s %s: Error allocating private data for format context ... aborting\n"),
1486
DEBUGFILE, DEBUGFUNCTION);
1490
// output_file->packet_size= mux_packet_size;
1491
// output_file->mux_rate= mux_rate;
1492
output_file->preload = (int) (0.5 * AV_TIME_BASE);
1493
output_file->max_delay = (int) (0.7 * AV_TIME_BASE);
1494
// output_file->loop_output = loop_output;
1496
// add the video stream and initialize the codecs
1500
add_video_stream (output_file, image,
1502
PIX_FMT_PAL8 ? PIX_FMT_RGB24 : input_pixfmt),
1503
xvc_codecs[job->targetCodec].ffmpeg_id, job);
1505
// FIXME: set params
1506
// memset (p_fParams, 0, sizeof(*p_fParams));
1507
// p_fParams->image_format = image_format;
1508
// p_fParams->time_base.den = out_st->codec->time_base.den;
1509
// p_fParams->time_base.num = out_st->codec->time_base.num;
1510
// p_fParams->width = out_st->codec->width;
1511
// p_fParams->height = out_st->codec->height;
1512
// if (av_set_parameters (output_file, p_fParams) < 0) {
1513
if (av_set_parameters (output_file, NULL) < 0) {
1515
_("%s %s: Invalid encoding parameters ... aborting\n"),
1516
DEBUGFILE, DEBUGFUNCTION);
1520
if (avcodec_open (out_st->codec, codec) < 0) {
1521
fprintf (stderr, _("%s %s: could not open video codec\n"),
1522
DEBUGFILE, DEBUGFUNCTION);
1525
#ifdef HAVE_FFMPEG_AUDIO
1526
if ((job->flags & FLG_REC_SOUND) && (job->au_targetCodec > 0)) {
1527
int au_ret = add_audio_stream (job);
1529
// initialize a mutex lock to its default value
1530
pthread_mutex_init (&mp, NULL);
1535
// create and start capture thread
1536
// initialized with default attributes
1537
tret = pthread_attr_init (&tattr);
1539
// create the thread
1541
pthread_create (&tid, &tattr,
1542
(void *) capture_audio_thread, job);
1545
#endif // HAVE_FFMPEG_AUDIO
1548
dump_format (output_file, 0, output_file->filename, 1);
1555
p_inpic = avcodec_alloc_frame ();
1557
if (input_pixfmt == PIX_FMT_PAL8) {
1559
malloc (avpicture_get_size
1560
(PIX_FMT_RGB24, image->width, image->height));
1561
if (!scratchbuf8bit) {
1563
"%s %s: Could not allocate buffer for 8bit palette conversion\n",
1564
DEBUGFILE, DEBUGFUNCTION);
1568
avpicture_fill ((AVPicture *) p_inpic, scratchbuf8bit,
1569
input_pixfmt, image->width, image->height);
1570
p_inpic->data[0] = scratchbuf8bit;
1571
p_inpic->linesize[0] = image->width * 3;
1573
avpicture_fill ((AVPicture *) p_inpic, (uint8_t *) image->data,
1574
input_pixfmt, image->width, image->height);
1578
p_outpic = avcodec_alloc_frame ();
1581
avpicture_get_size (out_st->codec->pix_fmt,
1582
out_st->codec->width, out_st->codec->height);
1583
outpic_buf = av_malloc (image_size);
1587
("%s %s: Could not allocate buffer for output frame! ... aborting\n"),
1588
DEBUGFILE, DEBUGFUNCTION);
1591
avpicture_fill ((AVPicture *) p_outpic, outpic_buf,
1592
out_st->codec->pix_fmt, out_st->codec->width,
1593
out_st->codec->height);
1596
* prepare output buffer for encoded frames
1598
if ((image_size + 20000) < FF_MIN_BUFFER_SIZE)
1599
outbuf_size = FF_MIN_BUFFER_SIZE;
1601
outbuf_size = image_size + 20000;
1602
outbuf = malloc (outbuf_size);
1606
("%s %s: Could not allocate buffer for encoded frame (outbuf)! ... aborting\n"),
1607
DEBUGFILE, DEBUGFUNCTION);
1611
if (!img_resample_ctx) {
1612
img_resample_ctx = sws_getContext (image->width,
1615
PIX_FMT_PAL8 ? PIX_FMT_RGB24
1617
out_st->codec->width,
1618
out_st->codec->height,
1619
out_st->codec->pix_fmt, 1,
1621
// sws_rgb2rgb_init(SWS_CPU_CAPS_MMX*0);
1623
// file preparation needs to be done once for multi-frame capture
1624
// and multiple times for single-frame capture
1625
if (job->target >= CAP_MF) {
1626
// prepare output filenames and register protocols
1627
// after this output_file->filename should have the right
1629
prepareOutputFile (job->file, output_file, job->movie_no);
1633
(&output_file->pb, output_file->filename, URL_WRONLY) < 0) {
1635
_("%s %s: Could not open '%s' ... aborting\n"),
1636
DEBUGFILE, DEBUGFUNCTION, output_file->filename);
1640
if (av_write_header (output_file) < 0) {
1641
dump_format (output_file, 0, output_file->filename, 1);
1644
("%s %s: Could not write header for output file (incorrect codec paramters ?) ... aborting\n"),
1645
DEBUGFILE, DEBUGFUNCTION);
1651
printf ("%s %s: leaving xffmpeg init\n", DEBUGFILE, DEBUGFUNCTION);
1653
printf ("%s %s: codec %p\n", DEBUGFILE, DEBUGFUNCTION, codec);
1654
printf ("%s %s: p_inpic %p\n", DEBUGFILE, DEBUGFUNCTION, p_inpic);
1655
printf ("%s %s: p_outpic %p\n", DEBUGFILE, DEBUGFUNCTION, p_outpic);
1656
printf ("%s %s: outpic_buf %p\n", DEBUGFILE, DEBUGFUNCTION, outpic_buf);
1657
printf ("%s %s: outbuf %p\n", DEBUGFILE, DEBUGFUNCTION, outbuf);
1659
printf ("%s %s: output_file %p\n", DEBUGFILE, DEBUGFUNCTION,
1661
printf ("%s %s: file_oformat %p\n", DEBUGFILE, DEBUGFUNCTION,
1663
printf ("%s %s: out_st %p\n", DEBUGFILE, DEBUGFUNCTION, out_st);
1665
printf ("%s %s: image size %i - input pixfmt %i - out_size %i\n",
1666
DEBUGFILE, DEBUGFUNCTION, image_size, input_pixfmt, out_size);
1667
printf ("%s %s: audio_pts %.f - video_pts %.f\n", DEBUGFILE,
1668
DEBUGFUNCTION, audio_pts, video_pts);
1670
printf ("%s %s: c_info %p - scratchbuf8bit %p\n", DEBUGFILE,
1671
DEBUGFUNCTION, job->c_info, scratchbuf8bit);
1675
if (job->target < CAP_MF) {
1676
// prepare output filenames and register protocols
1677
// after this output_file->filename should have the right filename
1678
prepareOutputFile (job->file, output_file, job->pic_no);
1681
if (url_fopen (&output_file->pb, output_file->filename, URL_WRONLY)
1683
fprintf (stderr, _("%s %s: Could not open '%s' ... aborting\n"),
1684
DEBUGFILE, DEBUGFUNCTION, output_file->filename);
1688
if (av_write_header (output_file) < 0) {
1689
dump_format (output_file, 0, output_file->filename, 1);
1692
("%s %s: Could not write header for output file (incorrect codec paramters ?) ... aborting\n"),
1693
DEBUGFILE, DEBUGFUNCTION);
1699
* convert input pic to pixel format the encoder expects
1702
if (input_pixfmt == PIX_FMT_ARGB32)
1703
dump32bit (image, job->c_info);
1704
if (input_pixfmt == PIX_FMT_PAL8)
1705
dump8bit (image, (u_int32_t *) job->color_table);
1708
/** \todo test if the special image conversion for Solaris is still
1710
if (input_pixfmt == PIX_FMT_ARGB32 && job->c_info->alpha_mask == 0xFF000000
1711
&& image->red_mask == 0xFF && image->green_mask == 0xFF00
1712
&& image->blue_mask == 0xFF0000) {
1713
myABGR32toARGB32 (image);
1714
} else if (input_pixfmt == PIX_FMT_PAL8) {
1715
myPAL8toRGB24 (image, p_inpic, job);
1717
// img resampling and conversion
1718
if (sws_scale (img_resample_ctx, p_inpic->data, p_inpic->linesize,
1719
0, image->height, p_outpic->data, p_outpic->linesize) < 0) {
1722
("%s %s: error converting or resampling frame: context %p, iwidth %i, iheight %i, owidth %i, oheight %i, inpfmt %i opfmt %i\n"),
1723
DEBUGFILE, DEBUGFUNCTION, img_resample_ctx, image->width,
1724
image->height, out_st->codec->width, out_st->codec->height,
1725
input_pixfmt, out_st->codec->pix_fmt);
1734
("%s %s: calling encode_video with codec %p, outbuf %p, outbuf size %i, output frame %p\n",
1735
DEBUGFILE, DEBUGFUNCTION, out_st->codec, outbuf, outbuf_size,
1740
avcodec_encode_video (out_st->codec, outbuf, outbuf_size, p_outpic);
1744
("%s %s: error encoding frame: c %p, outbuf %p, size %i, frame %p\n"),
1745
DEBUGFILE, DEBUGFUNCTION, out_st->codec, outbuf,
1746
outbuf_size, p_outpic);
1749
#ifdef HAVE_FFMPEG_AUDIO
1750
if (job->flags & FLG_REC_SOUND) {
1751
if (pthread_mutex_lock (&mp) > 0) {
1754
("mutex lock for writing video frame failed ... aborting\n"));
1758
#endif // HAVE_FFMPEG_AUDIO
1761
* write frame to file
1764
do_video_out (output_file, out_st, outbuf, out_size);
1767
if (job->target < CAP_MF)
1768
url_fclose (output_file->pb);
1770
#ifdef HAVE_FFMPEG_AUDIO
1774
if (job->flags & FLG_REC_SOUND) {
1775
if (pthread_mutex_unlock (&mp) > 0) {
1778
("couldn't release the mutex for writing video frame ... aborting\n"));
1781
#endif // HAVE_FFMPEG_AUDIO
1783
#undef DEBUGFUNCTION
1787
* \brief cleanup capture session
1792
#define DEBUGFUNCTION "FFMPEGClean()"
1793
Job *job = xvc_job_ptr ();
1796
printf ("%s %s: Entering\n", DEBUGFILE, DEBUGFUNCTION);
1799
#ifdef HAVE_FFMPEG_AUDIO
1800
if (job->flags & FLG_REC_SOUND && tid != 0) {
1804
// wait till audio thread is actually running, or else
1805
// the signal might kill xvidcap. we also cannot just
1806
// drop sending the signal, because the audio thread
1807
// might just be starting
1808
while (!audio_thread_running) {
1811
tret = pthread_kill (tid, SIGUSR1);
1813
pthread_join (tid, NULL);
1817
#endif // HAVE_FFMPEG_AUDIO
1823
av_write_trailer (output_file);
1830
* close file if multi-frame capture ... otherwise closed already
1832
if (job->target >= CAP_MF)
1833
url_fclose (output_file->pb);
1837
for (i = 0; i < output_file->nb_streams; i++) {
1838
if (output_file->streams[i]->codec) {
1839
avcodec_close (output_file->streams[i]->codec);
1840
av_free (output_file->streams[i]->codec);
1841
output_file->streams[i]->codec = NULL;
1843
av_free (output_file->streams[i]);
1847
#ifdef HAVE_FFMPEG_AUDIO
1850
#endif // HAVE_FFMPEG_AUDIO
1852
* free format context
1854
av_free (output_file->priv_data);
1855
output_file->priv_data = NULL;
1856
av_free (output_file);
1860
if (img_resample_ctx) {
1861
sws_freeContext (img_resample_ctx);
1862
img_resample_ctx = NULL;
1866
av_free (outpic_buf);
1869
av_free (outbuf); /* avcodec seems to do that job */
1873
av_free (outpic_buf);
1878
if (input_pixfmt == PIX_FMT_PAL8 && scratchbuf8bit) {
1879
free (scratchbuf8bit);
1880
scratchbuf8bit = NULL;
1884
#ifdef HAVE_FFMPEG_AUDIO
1886
#endif // HAVE_FFMPEG_AUDIO
1889
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1892
#undef DEBUGFUNCTION
1897
* \brief dump info about XImage for debugging purposes
1899
* @param img XImage to dump info about
1900
* @param fp handle for the file pointer to dump info into
1903
x2ffmpeg_dump_ximage_info (XImage * img, FILE * fp)
1905
#define DEBUGFUNCTION "x2ffmpeg_dump_ximage_info()"
1908
printf ("%s %s: Entering with image %p and file pointer %p\n",
1909
DEBUGFILE, DEBUGFUNCTION, img, fp);
1912
fprintf (fp, " width %d\n", img->width);
1913
fprintf (fp, " height %d\n", img->height);
1914
fprintf (fp, " xoffset %d\n", img->xoffset);
1915
fprintf (fp, " format %d\n", img->format);
1916
fprintf (fp, " data addr 0x%X\n", (int) img->data);
1917
fprintf (fp, " first four bytes of data 0x%X 0x%X 0x%X 0x%X\n",
1918
(unsigned char) (img->data[0]), (unsigned char) (img->data[1]),
1919
(unsigned char) img->data[2], (unsigned char) img->data[3]);
1920
fprintf (fp, " byte_order %s\n", img->byte_order ? "MSBFirst" : "LSBFirst");
1921
fprintf (fp, " bitmap_unit %d\n", img->bitmap_unit);
1922
fprintf (fp, " bitmap_bit_order %s\n",
1923
img->bitmap_bit_order ? "MSBFirst" : "LSBFirst");
1924
fprintf (fp, " bitmap_pad %d\n", img->bitmap_pad);
1925
fprintf (fp, " depth %d\n", img->depth);
1926
fprintf (fp, " bytes_per_line %d\n", img->bytes_per_line);
1927
fprintf (fp, " bits_per_pixel %d\n", img->bits_per_pixel);
1928
fprintf (fp, " red_mask 0x%.8lX\n", img->red_mask);
1929
fprintf (fp, " green_mask 0x%.8lX\n", img->green_mask);
1930
fprintf (fp, " blue_mask 0x%.8lX\n", img->blue_mask);
1933
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
1936
#undef DEBUGFUNCTION
1940
* \brief dump 32bit image to pnm for debugging purposes. The file written
1941
* is /tmp/pic.rgb.pnm
1943
* @param input XImage to dump to pnm
1946
dump32bit (const XImage * input, const ColorInfo * c_info)
1948
#define DEBUGFUNCTION "dump32bit()"
1951
static char head[256];
1953
static FILE *fp2 = NULL;
1954
uint8_t *ptr2, *output;
1957
register unsigned int
1958
rm = input->red_mask,
1959
gm = input->green_mask,
1960
bm = input->blue_mask,
1961
rs = c_info->red_shift,
1962
gs = c_info->green_shift,
1963
bs = c_info->blue_shift, *p32 = (unsigned int *) input->data;
1966
printf ("%s %s: Entering with image %p\n", DEBUGFILE, DEBUGFUNCTION, input);
1969
sprintf (head, "P6\n%d %d\n%d\n", input->width, input->height, 255);
1970
size = ((input->bytes_per_line * input->height) / 4) * 3;
1971
output = malloc (size);
1974
for (row = 0; row < input->height; row++) {
1975
for (col = 0; col < input->width; col++) {
1976
*output++ = ((*p32 & rm) >> rs);
1977
*output++ = ((*p32 & gm) >> gs);
1978
*output++ = ((*p32 & bm) >> bs);
1979
p32++; // ignore alpha values
1982
// eat paded bytes, for better speed we use shifting,
1983
// (bytes_per_line - bits_per_pixel / 8 * width ) / 4
1985
p32 += (input->bytes_per_line - (input->bits_per_pixel >> 3)
1986
* input->width) >> 2;
1989
fp2 = fopen ("/tmp/pic.rgb.pnm", "w");
1990
fwrite (head, strlen (head), 1, fp2);
1992
// x2ffmpeg_dump_ximage_info (input, fp2);
1994
fwrite (ptr2, size, 1, fp2);
1999
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
2002
#undef DEBUGFUNCTION
2006
* \brief dump 8bit image to ppm for debugging purposes. The file written
2007
* is /tmp/pic.rgb.pnm
2009
* @param input XImage to dump to ppm
2010
* @param ct pointer to color table
2013
dump8bit (const XImage * image, const u_int32_t * ct)
2015
#define DEBUGFUNCTION "dump8bit()"
2017
static char head[256];
2018
static unsigned int image_size;
2019
register unsigned char *line_ptr, *col_ptr;
2020
unsigned char *pnm_image = NULL;
2023
static FILE *fp2 = NULL;
2026
printf ("%s %s: Entering with image %p\n", DEBUGFILE, DEBUGFUNCTION, image);
2029
sprintf (head, "P6\n%d %d\n%d\n", image->width, image->height, 255);
2030
image_size = image->width * 3 * image->height; // RGB
2031
pnm_image = (unsigned char *) malloc (image_size);
2033
fp2 = fopen ("/tmp/pic.rgb.pnm", "w");
2034
fwrite (head, strlen (head), 1, fp2);
2036
line_ptr = pnm_image;
2037
for (row = 0; row < image->height; row++) {
2038
col_ptr = (unsigned char *) image->data + (row * image->bytes_per_line);
2039
for (col = 0; col < image->width; col++) {
2040
*line_ptr++ = ((ct[*col_ptr] & 0x00FF0000) >> 16);
2041
*line_ptr++ = ((ct[*col_ptr] & 0x0000FF00) >> 8);
2042
*line_ptr++ = (ct[*col_ptr] & 0x000000FF);
2046
fwrite (pnm_image, image_size, 1, fp2);
2049
// x2ffmpeg_dump_ximage_info (input, fp2);
2055
printf ("%s %s: Leaving\n", DEBUGFILE, DEBUGFUNCTION);
2058
#undef DEBUGFUNCTION
2063
#endif // USE_FFMPEG