ffmpeg2theora.c 101 KB
Newer Older
1
/* -*- tab-width:4;c-file-style:"cc-mode"; -*- */
2
/*
Jan Gerber's avatar
Jan Gerber committed
3
 * ffmpeg2theora.c -- Convert ffmpeg supported a/v files to  Ogg Theora / Ogg Vorbis
Jan Gerber's avatar
Jan Gerber committed
4
 * Copyright (C) 2003-2008 <j@v2v.cc>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Jan Gerber's avatar
Jan Gerber committed
19
 *
20
21
22
23
24
25
26
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <getopt.h>
27
#include <math.h>
28
#include <errno.h>
29

30
31
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
32
#ifdef HAVE_FRAMEHOOK
Jan Gerber's avatar
Jan Gerber committed
33
#include "libavformat/framehook.h"
34
#endif
35
36
#include "libswscale/swscale.h"
#include "libpostproc/postprocess.h"
37

Jan Gerber's avatar
Jan Gerber committed
38
#include "theora/theoraenc.h"
39
40
41
#include "vorbis/codec.h"
#include "vorbis/vorbisenc.h"

42
43
44
45
#ifdef WIN32
#include "fcntl.h"
#endif

46
#include "theorautils.h"
47
#include "iso639.h"
48
49
#include "subtitles.h"
#include "ffmpeg2theora.h"
50
#include "avinfo.h"
51

52
enum {
Jan Gerber's avatar
Jan Gerber committed
53
54
    NULL_FLAG,
    DEINTERLACE_FLAG,
Jan Gerber's avatar
Jan Gerber committed
55
    SOFTTARGET_FLAG,
Jan Gerber's avatar
Jan Gerber committed
56
57
58
    TWOPASS_FLAG,
    FIRSTPASS_FLAG,
    SECONDPASS_FLAG,
Jan Gerber's avatar
Jan Gerber committed
59
60
61
62
    OPTIMIZE_FLAG,
    SYNC_FLAG,
    NOAUDIO_FLAG,
    NOVIDEO_FLAG,
63
    NOSUBTITLES_FLAG,
Jan Gerber's avatar
Jan Gerber committed
64
65
66
67
68
69
70
71
72
    NOUPSCALING_FLAG,
    CROPTOP_FLAG,
    CROPBOTTOM_FLAG,
    CROPRIGHT_FLAG,
    CROPLEFT_FLAG,
    ASPECT_FLAG,
    MAXSIZE_FLAG,
    INPUTFPS_FLAG,
    AUDIOSTREAM_FLAG,
Jan Gerber's avatar
Jan Gerber committed
73
    VIDEOSTREAM_FLAG,
Jan Gerber's avatar
Jan Gerber committed
74
75
76
77
78
79
80
81
82
83
    SUBTITLES_FLAG,
    SUBTITLES_ENCODING_FLAG,
    SUBTITLES_LANGUAGE_FLAG,
    SUBTITLES_CATEGORY_FLAG,
    SUBTITLES_IGNORE_NON_UTF8_FLAG,
    VHOOK_FLAG,
    FRONTEND_FLAG,
    FRONTENDFILE_FLAG,
    SPEEDLEVEL_FLAG,
    PP_FLAG,
84
85
    NOSKELETON,
    INFO_FLAG
86
} F2T_FLAGS;
Jan Gerber's avatar
Jan Gerber committed
87

Jan Gerber's avatar
Jan Gerber committed
88
enum {
Jan Gerber's avatar
Jan Gerber committed
89
90
91
92
93
94
    V2V_PRESET_NONE,
    V2V_PRESET_PRO,
    V2V_PRESET_PREVIEW,
    V2V_PRESET_VIDEOBIN,
    V2V_PRESET_PADMA,
    V2V_PRESET_PADMASTREAM,
Jan Gerber's avatar
Jan Gerber committed
95
} F2T_PRESETS;
Jan Gerber's avatar
Jan Gerber committed
96

97

98
99
100
101
102
103
104
105
106
#define PAL_HALF_WIDTH 384
#define PAL_HALF_HEIGHT 288
#define NTSC_HALF_WIDTH 320
#define NTSC_HALF_HEIGHT 240

#define PAL_FULL_WIDTH 720
#define PAL_FULL_HEIGHT 576
#define NTSC_FULL_WIDTH 720
#define NTSC_FULL_HEIGHT 480
Jan Gerber's avatar
Jan Gerber committed
107

Jan Gerber's avatar
Jan Gerber committed
108
109
110

static int sws_flags = SWS_BICUBIC;

Jan Gerber's avatar
Jan Gerber committed
111
oggmux_info info;
112

113
114
static int using_stdin = 0;

Jan Gerber's avatar
Jan Gerber committed
115
116
static int padcolor[3] = { 16, 128, 128 };

117

Jan Gerber's avatar
Jan Gerber committed
118
119
120
121
122
123
static int ilog(unsigned _v){
  int ret;
  for(ret=0;_v;ret++)_v>>=1;
  return ret;
}

124
/**
Jan Gerber's avatar
Jan Gerber committed
125
 * Allocate and initialise an AVFrame.
126
 */
Jan Gerber's avatar
Jan Gerber committed
127
static AVFrame *frame_alloc(int pix_fmt, int width, int height) {
Jan Gerber's avatar
Jan Gerber committed
128
129
130
131
    AVFrame *picture;
    uint8_t *picture_buf;
    int size;

Jan Gerber's avatar
Jan Gerber committed
132
    picture = avcodec_alloc_frame();
Jan Gerber's avatar
Jan Gerber committed
133
134
135
136
    if (!picture)
        return NULL;
    size = avpicture_get_size (pix_fmt, width, height);
    picture_buf = av_malloc (size);
Jan Gerber's avatar
Jan Gerber committed
137
    if (!picture_buf) {
Jan Gerber's avatar
Jan Gerber committed
138
139
140
        av_free (picture);
        return NULL;
    }
Jan Gerber's avatar
Jan Gerber committed
141
    avpicture_fill((AVPicture *) picture, picture_buf, pix_fmt, width, height);
Jan Gerber's avatar
Jan Gerber committed
142
    return picture;
143
144
}

145
146
147
/**
 * Frees an AVFrame.
 */
Jan Gerber's avatar
Jan Gerber committed
148
static void frame_dealloc(AVFrame *frame) {
149
    if (frame) {
Jan Gerber's avatar
Jan Gerber committed
150
        avpicture_free((AVPicture*)frame);
151
152
153
154
        av_free(frame);
    }
}

155
156
157
158
/**
 * initialize ff2theora with default values
 * @return ff2theora struct
 */
Jan Gerber's avatar
Jan Gerber committed
159
static ff2theora ff2theora_init() {
Jan Gerber's avatar
Jan Gerber committed
160
    ff2theora this = calloc (1, sizeof (*this));
Jan Gerber's avatar
Jan Gerber committed
161
    if (this != NULL) {
Jan Gerber's avatar
Jan Gerber committed
162
        this->disable_audio=0;
163
        this->disable_video=0;
164
        this->disable_subtitles=0;
165
        this->no_upscaling=0;
Jan Gerber's avatar
Jan Gerber committed
166
167
168
169
170
171
        this->video_index = -1;
        this->audio_index = -1;
        this->start_time=0;
        this->end_time=0; /* 0 denotes no end time set */

        // audio
172
173
        this->sample_rate = -1;  // samplerate hmhmhm
        this->channels = -1;
174
        this->audio_quality = 1.00;// audio quality 1
Jan Gerber's avatar
Jan Gerber committed
175
        this->audio_bitrate=0;
176
        this->audiostream = -1;
Jan Gerber's avatar
Jan Gerber committed
177

Jan Gerber's avatar
Jan Gerber committed
178
        // video
Jan Gerber's avatar
Jan Gerber committed
179
        this->videostream = -1;
Jan Gerber's avatar
Jan Gerber committed
180
181
        this->picture_width=0;      // set to 0 to not resize the output
        this->picture_height=0;      // set to 0 to not resize the output
Jan Gerber's avatar
Jan Gerber committed
182
        this->video_quality=-1; // defaults set later
Jan Gerber's avatar
Jan Gerber committed
183
        this->video_bitrate=0;
Jan Gerber's avatar
Jan Gerber committed
184
        this->keyint=0;
185
186
        this->force_input_fps.num = -1;
        this->force_input_fps.den = 1;
187
        this->sync=0;
Jan Gerber's avatar
Jan Gerber committed
188
189
190
        this->aspect_numerator=0;
        this->aspect_denominator=0;
        this->frame_aspect=0;
191
        this->max_size=-1;
Jan Gerber's avatar
Jan Gerber committed
192
        this->deinterlace=0; // auto by default, if input is flaged as interlaced it will deinterlace.
Jan Gerber's avatar
Jan Gerber committed
193
194
        this->soft_target=0;
        this->buf_delay=-1;
Jan Gerber's avatar
Jan Gerber committed
195
        this->vhook=0;
196
197
        this->framerate_new.num = -1;
        this->framerate_new.den = 1;
Jan Gerber's avatar
Jan Gerber committed
198

Jan Gerber's avatar
Jan Gerber committed
199
200
201
202
        this->frame_topBand=0;
        this->frame_bottomBand=0;
        this->frame_leftBand=0;
        this->frame_rightBand=0;
Jan Gerber's avatar
Jan Gerber committed
203

204
205
        this->n_kate_streams=0;
        this->kate_streams=NULL;
206
        this->ignore_non_utf8 = 0;
207

Jan Gerber's avatar
Jan Gerber committed
208
        this->pix_fmt = PIX_FMT_YUV420P;
209
210
211
212
213
214
215
216
217

        // ffmpeg2theora --nosound -f dv -H 32000 -S 0 -v 8 -x 384 -y 288 -G 1.5 input.dv
        this->video_gamma  = 0.0;
        this->video_bright = 0.0;
        this->video_contr  = 0.0;
        this->video_satur  = 1.0;

        this->y_lut_used = 0;
        this->uv_lut_used = 0;
Jan Gerber's avatar
Jan Gerber committed
218
219
    }
    return this;
220
221
}

222
223
224
225
226
227
228
229
230
// gamma lookup table code

static void y_lut_init(ff2theora this) {
    int i;
    double v;

    double c = this->video_contr;
    double b = this->video_bright;
    double g = this->video_gamma;
Jan Gerber's avatar
Jan Gerber committed
231

232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
    if ((g < 0.01) || (g > 100.0)) g = 1.0;
    if ((c < 0.01) || (c > 100.0)) c = 1.0;
    if ((b < -1.0) || (b > 1.0))   b = 0.0;

    if (g == 1.0 && c == 1.0 && b == 0.0) return;
    this->y_lut_used = 1;

    printf("  Video correction: gamma=%g, contrast=%g, brightness=%g\n", g, c, b);

    g = 1.0 / g;    // larger values shall make brighter video.

    for (i = 0; i < 256; i++) {
        v = (double) i / 255.0;
        v = c * v + b * 0.1;
        if (v < 0.0) v = 0.0;
        v = pow(v, g) * 255.0;    // mplayer's vf_eq2.c multiplies with 256 here, strange...

        if (v >= 255)
            this->y_lut[i] = 255;
        else
            this->y_lut[i] = (unsigned char)(v+0.5);
    }
}


static void uv_lut_init(ff2theora this) {
    int i;
    double v, s;
    s = this->video_satur;

    if ((s < 0.0) || (s > 100.0)) s = 1.0;

    if (s == 1.0) return;
    this->uv_lut_used = 1;

    printf("  Color correction: saturation=%g\n", s);

    for (i = 0; i < 256; i++) {
        v = 127.0 + (s * ((double)i - 127.0));
        if (v < 0.0) v = 0.0;

        if (v >= 255.0)
            this->uv_lut[i] = 255;
        else
            this->uv_lut[i] = (unsigned char)(v+0.5);
    }
}

static void lut_init(ff2theora this) {
    y_lut_init(this);
    uv_lut_init(this);
}

static void lut_apply(unsigned char *lut, unsigned char *src, unsigned char *dst, int width, int height, int stride) {
    int x, y;

    for (y = 0; y < height; y++) {
        for (x = 0; x < width; x++) {
            dst[x] = lut[src[x]];
        }
        src += stride;
        dst += stride;
    }
}

Jan Gerber's avatar
Jan Gerber committed
297
static void prepare_ycbcr_buffer(ff2theora this, th_ycbcr_buffer ycbcr, AVFrame *frame) {
298
    int i;
Jan Gerber's avatar
Jan Gerber committed
299
    /* pysical pages */
Jan Gerber's avatar
Jan Gerber committed
300
301
302
303
    ycbcr[0].width = this->frame_width;
    ycbcr[0].height = this->frame_height;
    ycbcr[0].stride = frame->linesize[0];
    ycbcr[0].data = frame->data[0];
Jan Gerber's avatar
Jan Gerber committed
304

Jan Gerber's avatar
Jan Gerber committed
305
306
307
308
    ycbcr[1].width = this->frame_width / 2;
    ycbcr[1].height = this->frame_height / 2;
    ycbcr[1].stride = frame->linesize[1];
    ycbcr[1].data = frame->data[1];
Jan Gerber's avatar
Jan Gerber committed
309

Jan Gerber's avatar
Jan Gerber committed
310
311
312
313
    ycbcr[2].width = this->frame_width / 2;
    ycbcr[2].height = this->frame_height / 2;
    ycbcr[2].stride = frame->linesize[1];
    ycbcr[2].data = frame->data[2];
314

315
    if (this->y_lut_used) {
Jan Gerber's avatar
Jan Gerber committed
316
        lut_apply(this->y_lut, ycbcr[0].data, ycbcr[0].data, ycbcr[0].width, ycbcr[0].height, ycbcr[0].stride);
Jan Gerber's avatar
Jan Gerber committed
317
    }
318
    if (this->uv_lut_used) {
Jan Gerber's avatar
Jan Gerber committed
319
320
        lut_apply(this->uv_lut, ycbcr[1].data, ycbcr[1].data, ycbcr[1].width, ycbcr[1].height, ycbcr[1].stride);
        lut_apply(this->uv_lut, ycbcr[2].data, ycbcr[2].data, ycbcr[2].width, ycbcr[2].height, ycbcr[2].stride);
Jan Gerber's avatar
Jan Gerber committed
321
322
323
    }
}

324
325
326
327
328
329
330
static int is_supported_subtitle_stream(ff2theora this, int idx)
{
  AVCodecContext *enc = this->context->streams[idx]->codec;
  if (enc->codec_type != CODEC_TYPE_SUBTITLE) return 0;
  switch (enc->codec_id) {
    case CODEC_ID_TEXT:
    case CODEC_ID_SSA:
331
    case CODEC_ID_MOV_TEXT:
332
333
334
335
336
337
338
      return 1;
    default:
      return 0;
  }
  return 0;
}

339
static char *get_raw_text_from_ssa(const char *ssa)
340
{
341
  int n,intag,inescape;
342
  char *multiblock = NULL, *realloced_mb;
343
344
345
346
  char *allocated;
  const char *dialogue, *ptr, *tag_start;

  if (!ssa) return NULL;
347
348
349
350
351
352
353
354
355
356
357

  /* turns out some SSA packets have several blocks, each on a single line, so loop */
  while (ssa) {
    dialogue=strstr(ssa, "Dialogue:");
    if (!dialogue) break;

    ptr = dialogue;
    for (n=0;n<9;++n) {
      ptr=strchr(ptr,',');
      if (!ptr) return NULL;
      ++ptr;
358
    }
359
360
361
362
363
364
365
366
367
368
    dialogue = ptr;
    allocated = strdup(dialogue);

    /* find all "{...}" tags - the following must work for UTF-8 */
    intag=inescape=0;
    n=0;
    for (ptr=dialogue; *ptr && *ptr!='\n'; ++ptr) {
      if (*ptr=='{') {
        if (intag==0) tag_start = ptr;
        ++intag;
369
      }
370
371
372
373
374
      else if (*ptr=='}') {
        --intag;
        if (intag == 0) {
          /* tag parsing - none for now */
        }
375
      }
376
377
378
379
380
381
382
      else if (!intag) {
        if (inescape) {
          if (*ptr == 'N' || *ptr == 'n')
            allocated[n++] = '\n';
          else if (*ptr == 'h')
            allocated[n++] = ' ';
          inescape=0;
383
384
        }
        else {
385
386
387
388
389
390
          if (*ptr=='\\') {
            inescape=1;
          }
          else {
            allocated[n++]=*ptr;
          }
391
392
393
        }
      }
    }
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    allocated[n]=0;

    /* skip over what we read */
    ssa = ptr;

    /* remove any trailing newlines (also \r characters) */
    n = strlen(allocated);
    while (n>0 && (allocated[n-1]=='\n' || allocated[n-1]=='\r'))
      allocated[--n]=0;

    /* add this new block */
    realloced_mb = (char*)realloc(multiblock, (multiblock?strlen(multiblock):0) + strlen(allocated) + 2); /* \n + 0 */
    if (realloced_mb) {
      if (multiblock) strcat(realloced_mb, "\n"); else strcpy(realloced_mb, "");
      strcat(realloced_mb, allocated);
      multiblock = realloced_mb;
      free(allocated);
    }
412
413
  }

414
  return multiblock;
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
}

static const float get_ssa_time(const char *p)
{
    int hour, min, sec, hsec;
    int r;

    if(sscanf(p, "%d:%d:%d%*c%d", &hour, &min, &sec, &hsec) != 4)
        return 0;

    min+= 60*hour;
    sec+= 60*min;
    return (float)(sec*100+hsec)/100;
}

static const float get_duration_from_ssa(const char *ssa)
{
  int n;
  float d = 2.0f;
  double start, end;
  const char *ptr=ssa;

  ptr=strchr(ptr,',');
  if (!ptr) return d;
  ptr++;
  start = get_ssa_time(ptr);
  ptr=strchr(ptr,',');
  if (!ptr) return d;
  ptr++;
  end = get_ssa_time(ptr);

  return end-start;
}

static const char *find_language_for_subtitle_stream(const AVStream *s)
{
  const char *lang=find_iso639_1(s->language);
  if (!lang) {
    fprintf(stderr,"WARNING - unrecognized ISO 639-2 language code: %s\n",s->language);
  }
  return lang;
}

458
void ff2theora_output(ff2theora this) {
459
    unsigned int i;
Jan Gerber's avatar
Jan Gerber committed
460
461
462
463
464
465
    AVCodecContext *aenc = NULL;
    AVCodecContext *venc = NULL;
    AVStream *astream = NULL;
    AVStream *vstream = NULL;
    AVCodec *acodec = NULL;
    AVCodec *vcodec = NULL;
466
467
    pp_mode_t *ppMode = NULL;
    pp_context_t *ppContext = NULL;
Jan Gerber's avatar
Jan Gerber committed
468
    float frame_aspect = 0;
469
    double fps = 0.0;
470
    AVRational vstream_fps;
471
    int display_width, display_height;
472
473
    char *subtitles_enabled = (char*)alloca(this->context->nb_streams);
    char *subtitles_opened = (char*)alloca(this->context->nb_streams);
474
    int synced = this->start_time == 0.0;
Jan Gerber's avatar
Jan Gerber committed
475

Jan Gerber's avatar
Jan Gerber committed
476
    if (this->audiostream >= 0 && this->context->nb_streams > this->audiostream) {
477
        AVCodecContext *enc = this->context->streams[this->audiostream]->codec;
478
479
        if (enc->codec_type == CODEC_TYPE_AUDIO) {
            this->audio_index = this->audiostream;
480
            fprintf(stderr, "  Using stream #0.%d as audio input\n",this->audio_index);
481
482
        }
        else {
483
            fprintf(stderr, "  The selected stream is not audio, falling back to automatic selection\n");
484
485
        }
    }
Jan Gerber's avatar
Jan Gerber committed
486
487
488
489
490
491
492
493
494
495
    if (this->videostream >= 0 && this->context->nb_streams > this->videostream) {
        AVCodecContext *enc = this->context->streams[this->videostream]->codec;
        if (enc->codec_type == CODEC_TYPE_VIDEO) {
            this->video_index = this->videostream;
            fprintf(stderr, "  Using stream #0.%d as video input\n",this->video_index);
        }
        else {
            fprintf(stderr, "  The selected stream is not video, falling back to automatic selection\n");
        }
    }
Jan Gerber's avatar
Jan Gerber committed
496

Jan Gerber's avatar
Jan Gerber committed
497
    for (i = 0; i < this->context->nb_streams; i++) {
498
        AVCodecContext *enc = this->context->streams[i]->codec;
Jan Gerber's avatar
Jan Gerber committed
499
        switch (enc->codec_type) {
500
            case CODEC_TYPE_VIDEO:
Jan Gerber's avatar
Jan Gerber committed
501
                if (this->video_index < 0 && !this->disable_video)
502
503
504
505
506
507
508
509
                    this->video_index = i;
                break;
            case CODEC_TYPE_AUDIO:
                if (this->audio_index < 0 && !this->disable_audio)
                    this->audio_index = i;
                break;
            default:
                break;
Jan Gerber's avatar
Jan Gerber committed
510
511
512
        }
    }

Jan Gerber's avatar
Jan Gerber committed
513
    if (this->video_index >= 0) {
Jan Gerber's avatar
Jan Gerber committed
514
        vstream = this->context->streams[this->video_index];
Jan Gerber's avatar
Jan Gerber committed
515
516
        venc = vstream->codec;

Jan Gerber's avatar
Jan Gerber committed
517
        vcodec = avcodec_find_decoder (venc->codec_id);
518
519
        display_width = venc->width;
        display_height = venc->height;
Jan Gerber's avatar
Jan Gerber committed
520

Jan Gerber's avatar
Jan Gerber committed
521
        if (vstream->time_base.den && vstream->time_base.num
522
523
524
525
526
527
528
529
530
531
                                  && av_q2d(vstream->time_base) > 0.001) {
            vstream_fps.num = vstream->time_base.den;
            vstream_fps.den =  vstream->time_base.num;
            fps = 1/av_q2d(vstream->time_base);
        } else {
            fps = (double) vstream->r_frame_rate.num / vstream->r_frame_rate.den;
            vstream_fps.num = vstream->r_frame_rate.num;
            vstream_fps.den = vstream->r_frame_rate.den;
        }

Jan Gerber's avatar
Jan Gerber committed
532
533
534
        if (fps > 10000)
            fps /= 1000;

Jan Gerber's avatar
Jan Gerber committed
535
        if (this->force_input_fps.num > 0)
536
            fps=(double)this->force_input_fps.num / this->force_input_fps.den;
537
        if (vcodec == NULL || avcodec_open (venc, vcodec) < 0) {
Jan Gerber's avatar
Jan Gerber committed
538
            this->video_index = -1;
539
        }
Jan Gerber's avatar
Jan Gerber committed
540
        this->fps = fps;
541

Jan Gerber's avatar
Jan Gerber committed
542
        if (this->picture_width && !this->picture_height) {
543
            this->picture_height = this->picture_width / ((double)display_width/display_height);
Jan Gerber's avatar
Jan Gerber committed
544
            this->picture_height = this->picture_height - this->picture_height%2;
545
        }
Jan Gerber's avatar
Jan Gerber committed
546
        if (this->picture_height && !this->picture_width) {
547
            this->picture_width = this->picture_height * ((double)display_width/display_height);
Jan Gerber's avatar
Jan Gerber committed
548
            this->picture_width = this->picture_width - this->picture_width%2;
549
        }
550

Jan Gerber's avatar
Jan Gerber committed
551
552
        if (this->preset == V2V_PRESET_PREVIEW) {
            if (abs(this->fps-30)<1 && (display_width!=NTSC_HALF_WIDTH || display_height!=NTSC_HALF_HEIGHT) ) {
553
554
                this->picture_width=NTSC_HALF_WIDTH;
                this->picture_height=NTSC_HALF_HEIGHT;
Jan Gerber's avatar
Jan Gerber committed
555
            }
Jan Gerber's avatar
Jan Gerber committed
556
557
558
559
            else {
                this->picture_width=PAL_HALF_WIDTH;
                this->picture_height=PAL_HALF_HEIGHT;
            }
Jan Gerber's avatar
Jan Gerber committed
560
        }
Jan Gerber's avatar
Jan Gerber committed
561
562
        else if (this->preset == V2V_PRESET_PRO) {
            if (abs(this->fps-30)<1 && (display_width!=NTSC_FULL_WIDTH || display_height!=NTSC_FULL_HEIGHT) ) {
563
564
                this->picture_width=NTSC_FULL_WIDTH;
                this->picture_height=NTSC_FULL_HEIGHT;
Jan Gerber's avatar
Jan Gerber committed
565
            }
Jan Gerber's avatar
Jan Gerber committed
566
567
568
569
            else {
                this->picture_width=PAL_FULL_WIDTH;
                this->picture_height=PAL_FULL_HEIGHT;
            }
Jan Gerber's avatar
Jan Gerber committed
570
        }
Jan Gerber's avatar
Jan Gerber committed
571
        else if (this->preset == V2V_PRESET_PADMA) {
572
573
            int width=display_width-this->frame_leftBand-this->frame_rightBand;
            int height=display_height-this->frame_topBand-this->frame_bottomBand;
Jan Gerber's avatar
Jan Gerber committed
574
575
            if (vstream->sample_aspect_ratio.den!=0 && vstream->sample_aspect_ratio.num!=0) {
                height=((float)vstream->sample_aspect_ratio.den/vstream->sample_aspect_ratio.num) * height;
Jan Gerber's avatar
Jan Gerber committed
576
            }
Jan Gerber's avatar
Jan Gerber committed
577
578
579
580
581
582
583
584
585
586
587
588
            if (this->frame_aspect == 0)
                this->frame_aspect = (float)width/height;
            if (this->frame_aspect <= 1.5) {
                if (width > 640 || height > 480) {
                    //4:3 640 x 480
                    this->picture_width=640;
                    this->picture_height=480;
                }
                else {
                    this->picture_width=width;
                    this->picture_height=height;
                }
Jan Gerber's avatar
Jan Gerber committed
589
590
            }
            else {
Jan Gerber's avatar
Jan Gerber committed
591
592
593
594
595
596
597
598
599
                if (width > 640 || height > 360) {
                    //16:9 640 x 360
                    this->picture_width=640;
                    this->picture_height=360;
                }
                else {
                    this->picture_width=width;
                    this->picture_height=height;
                }
Jan Gerber's avatar
Jan Gerber committed
600
601
            }
        }
Jan Gerber's avatar
Jan Gerber committed
602
603
604
        else if (this->preset == V2V_PRESET_PADMASTREAM) {
            int width=display_width-this->frame_leftBand-this->frame_rightBand;
            int height=display_height-this->frame_topBand-this->frame_bottomBand;
Jan Gerber's avatar
Jan Gerber committed
605
606
            if (vstream->sample_aspect_ratio.den!=0 && vstream->sample_aspect_ratio.num!=0) {
                height=((float)vstream->sample_aspect_ratio.den/vstream->sample_aspect_ratio.num) * height;
Jan Gerber's avatar
Jan Gerber committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
            }
            if (this->frame_aspect == 0)
                this->frame_aspect = (float)width/height;
            if (this->frame_aspect <= 1.5) {
                this->picture_width=128;
                this->picture_height=96;
            }
            else {
                this->picture_width=128;
                this->picture_height=72;
            }
        }
        else if (this->preset == V2V_PRESET_VIDEOBIN) {
            int width=display_width-this->frame_leftBand-this->frame_rightBand;
            int height=display_height-this->frame_topBand-this->frame_bottomBand;
Jan Gerber's avatar
Jan Gerber committed
622
623
            if (vstream->sample_aspect_ratio.den!=0 && vstream->sample_aspect_ratio.num!=0) {
                height=((float)vstream->sample_aspect_ratio.den/vstream->sample_aspect_ratio.num) * height;
Jan Gerber's avatar
Jan Gerber committed
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
            }
            if ( ((float)width /height) <= 1.5) {
                if (width > 448) {
                    //4:3 448 x 336
                    this->picture_width=448;
                    this->picture_height=336;
                }
                else {
                    this->picture_width=width;
                    this->picture_height=height;
                }
            }
            else {
                if (width > 512) {
                    //16:9 512 x 288
                    this->picture_width=512;
                    this->picture_height=288;
                }
                else {
                    this->picture_width=width;
                    this->picture_height=height;
                }
            }
        }
        if (this->max_size > 0) {
            int width = display_width-this->frame_leftBand-this->frame_rightBand;
            int height = display_height-this->frame_topBand-this->frame_bottomBand;
Jan Gerber's avatar
Jan Gerber committed
651
652
            if (vstream->sample_aspect_ratio.den!=0 && vstream->sample_aspect_ratio.num!=0) {
                height = ((float)vstream->sample_aspect_ratio.den/vstream->sample_aspect_ratio.num) * height;
Jan Gerber's avatar
Jan Gerber committed
653
654
655
656
657
658
659
660
661
662
663
664
            }
            if (this->frame_aspect == 0)
                this->frame_aspect = (float)width/height;
            if (width > height) {
                this->picture_width = this->max_size;
                this->picture_height = this->max_size / this->frame_aspect;
                this->picture_height = this->picture_height + this->picture_height%2;
            } else {
                this->picture_height = this->max_size;
                this->picture_width = this->max_size * this->frame_aspect;
                this->picture_width = this->picture_width + this->picture_width%2;
            }
665
        }
666

Jan Gerber's avatar
Jan Gerber committed
667
668
        if (this->no_upscaling) {
            if (this->picture_width && this->picture_width > display_width) {
669
670
                this->picture_width = display_width;
                this->picture_height = display_height;
671
            }
Jan Gerber's avatar
Jan Gerber committed
672
            if (this->fps < (double)this->framerate_new.num / this->framerate_new.den) {
673
674
                this->framerate_new.num = vstream_fps.num;
                this->framerate_new.den = vstream_fps.den;
675
676
677
            }
        }

Jan Gerber's avatar
Jan Gerber committed
678
679
        if (this->picture_height==0 &&
            (this->frame_leftBand || this->frame_rightBand || this->frame_topBand || this->frame_bottomBand) ) {
680
            this->picture_height=display_height-
Jan Gerber's avatar
Jan Gerber committed
681
682
                    this->frame_topBand-this->frame_bottomBand;
        }
Jan Gerber's avatar
Jan Gerber committed
683
684
        if (this->picture_width==0 &&
            (this->frame_leftBand || this->frame_rightBand || this->frame_topBand || this->frame_bottomBand) ) {
685
            this->picture_width=display_width-
Jan Gerber's avatar
Jan Gerber committed
686
687
688
                    this->frame_leftBand-this->frame_rightBand;
        }
        //so frame_aspect is set on the commandline
Jan Gerber's avatar
Jan Gerber committed
689
690
        if (this->frame_aspect != 0) {
            if (this->picture_height) {
691
692
693
694
                this->aspect_numerator = 10000*this->frame_aspect*this->picture_height;
                this->aspect_denominator = 10000*this->picture_width;
            }
            else{
695
696
                this->aspect_numerator = 10000*this->frame_aspect*display_height;
                this->aspect_denominator = 10000*display_width;
697
698
699
            }
            av_reduce(&this->aspect_numerator,&this->aspect_denominator,this->aspect_numerator,this->aspect_denominator,10000);
            frame_aspect=this->frame_aspect;
Jan Gerber's avatar
Jan Gerber committed
700
        }
Jan Gerber's avatar
Jan Gerber committed
701
        if (vstream->sample_aspect_ratio.num!=0 && this->frame_aspect==0) {
Jan Gerber's avatar
Jan Gerber committed
702
            // just use the ratio from the input
Jan Gerber's avatar
Jan Gerber committed
703
704
            this->aspect_numerator=vstream->sample_aspect_ratio.num;
            this->aspect_denominator=vstream->sample_aspect_ratio.den;
Jan Gerber's avatar
Jan Gerber committed
705
            // or we use ratio for the output
Jan Gerber's avatar
Jan Gerber committed
706
            if (this->picture_height) {
707
708
                int width=display_width-this->frame_leftBand-this->frame_rightBand;
                int height=display_height-this->frame_topBand-this->frame_bottomBand;
Jan Gerber's avatar
Jan Gerber committed
709
                av_reduce(&this->aspect_numerator,&this->aspect_denominator,
Jan Gerber's avatar
Jan Gerber committed
710
711
                vstream->sample_aspect_ratio.num*width*this->picture_height,
                vstream->sample_aspect_ratio.den*height*this->picture_width,10000);
Jan Gerber's avatar
Jan Gerber committed
712
713
714
715
                frame_aspect=(float)(this->aspect_numerator*this->picture_width)/
                                (this->aspect_denominator*this->picture_height);
            }
            else{
716
717
                frame_aspect=(float)(this->aspect_numerator*display_width)/
                                (this->aspect_denominator*display_height);
Jan Gerber's avatar
Jan Gerber committed
718
719
            }
        }
Jan Gerber's avatar
Jan Gerber committed
720

Jan Gerber's avatar
Jan Gerber committed
721
722
723
724
725
        if ((float)this->aspect_numerator/this->aspect_denominator < 1.09) {
            this->aspect_numerator = 1;
            this->aspect_denominator = 1;
            frame_aspect=(float)(this->aspect_numerator*this->picture_width)/
                                (this->aspect_denominator*this->picture_height);
Jan Gerber's avatar
Jan Gerber committed
726
        }
727
        if (!(info.twopass==3 && info.passno==2) && !info.frontend && this->aspect_denominator && frame_aspect) {
728
            fprintf(stderr, "  Pixel Aspect Ratio: %.2f/1 ",(float)this->aspect_numerator/this->aspect_denominator);
Jan Gerber's avatar
Jan Gerber committed
729
            fprintf(stderr, "  Frame Aspect Ratio: %.2f/1\n", frame_aspect);
Jan Gerber's avatar
Jan Gerber committed
730
731
        }

732
        if (!(info.twopass==3 && info.passno==2) && !info.frontend && this->deinterlace==1)
733
            fprintf(stderr, "  Deinterlace: on\n");
734
735

        if (strcmp(this->pp_mode, "")) {
Jan Gerber's avatar
Jan Gerber committed
736
737
            ppContext = pp_get_context(display_width, display_height, PP_FORMAT_420);
            ppMode = pp_get_mode_by_name_and_quality(this->pp_mode, PP_QUALITY_MAX);
738
            if(!(info.twopass==3 && info.passno==2) && !info.frontend)
Jan Gerber's avatar
Jan Gerber committed
739
                fprintf(stderr, "  Postprocessing: %s\n", this->pp_mode);
740
741
        }

Jan Gerber's avatar
Jan Gerber committed
742
        if (!this->picture_width)
743
            this->picture_width = display_width;
Jan Gerber's avatar
Jan Gerber committed
744
        if (!this->picture_height)
745
            this->picture_height = display_height;
746

747
748
749
750
        /* Theora has a divisible-by-sixteen restriction for the encoded video size */
        /* scale the frame size up to the nearest /16 and calculate offsets */
        this->frame_width = ((this->picture_width + 15) >>4)<<4;
        this->frame_height = ((this->picture_height + 15) >>4)<<4;
Jan Gerber's avatar
Jan Gerber committed
751

Jan Gerber's avatar
Jan Gerber committed
752
753
754
755
        /*Force the offsets to be even so that chroma samples line up like we
           expect.*/
        this->frame_x_offset = this->frame_width-this->picture_width>>1&~1;
        this->frame_y_offset = this->frame_height-this->picture_height>>1&~1;
Jan Gerber's avatar
Jan Gerber committed
756

Jan Gerber's avatar
Jan Gerber committed
757
        if (this->frame_width > 0 || this->frame_height > 0) {
Jan Gerber's avatar
Jan Gerber committed
758
            this->sws_colorspace_ctx = sws_getContext(
Jan Gerber's avatar
Jan Gerber committed
759
760
761
                            display_width, display_height, venc->pix_fmt,
                            display_width, display_height, this->pix_fmt,
                            sws_flags, NULL, NULL, NULL
Jan Gerber's avatar
Jan Gerber committed
762
763
            );
            this->sws_scale_ctx = sws_getContext(
Jan Gerber's avatar
Jan Gerber committed
764
765
766
767
768
                        display_width - (this->frame_leftBand + this->frame_rightBand),
                        display_height - (this->frame_topBand + this->frame_bottomBand),
                        this->pix_fmt,
                        this->picture_width, this->picture_height, this->pix_fmt,
                        sws_flags, NULL, NULL, NULL
Jan Gerber's avatar
Jan Gerber committed
769
            );
Jan Gerber's avatar
Jan Gerber committed
770
            if (!info.frontend && !(info.twopass==3 && info.passno==2)) {
Jan Gerber's avatar
Jan Gerber committed
771
772
773
774
775
                if (this->frame_topBand || this->frame_bottomBand ||
                    this->frame_leftBand || this->frame_rightBand ||
                    this->picture_width != (display_width-this->frame_leftBand - this->frame_rightBand) ||
                    this->picture_height != (display_height-this->frame_topBand-this->frame_bottomBand))
                    fprintf(stderr, "  Resize: %dx%d", display_width, display_height);
Jan Gerber's avatar
Jan Gerber committed
776
777
778
779
780
781
782
783
784
785
                if (this->frame_topBand || this->frame_bottomBand ||
                    this->frame_leftBand || this->frame_rightBand) {
                    fprintf(stderr, " => %dx%d",
                        display_width-this->frame_leftBand-this->frame_rightBand,
                        display_height-this->frame_topBand-this->frame_bottomBand);
                }
                if (this->picture_width != (display_width-this->frame_leftBand - this->frame_rightBand)
                    || this->picture_height != (display_height-this->frame_topBand-this->frame_bottomBand))
                    fprintf(stderr, " => %dx%d",this->picture_width, this->picture_height);
                fprintf(stderr, "\n");
Jan Gerber's avatar
Jan Gerber committed
786
787
            }
        }
788

789
        lut_init(this);
Jan Gerber's avatar
Jan Gerber committed
790
    }
791
    if (!(info.twopass==3 && info.passno==2) && !info.frontend && this->framerate_new.num > 0 && this->fps != (double)this->framerate_new.num / this->framerate_new.den) {
Jan Gerber's avatar
Jan Gerber committed
792
        fprintf(stderr, "  Resample Framerate: %0.3f => %0.3f\n",
793
                        this->fps, (double)this->framerate_new.num / this->framerate_new.den);
794
    }
Jan Gerber's avatar
Jan Gerber committed
795
    if (this->audio_index >= 0) {
Jan Gerber's avatar
Jan Gerber committed
796
        astream = this->context->streams[this->audio_index];
797
        aenc = this->context->streams[this->audio_index]->codec;
Jan Gerber's avatar
Jan Gerber committed
798
        acodec = avcodec_find_decoder (aenc->codec_id);
799
        if (this->channels < 1) {
800
            this->channels = aenc->channels;
801
        }
Jan Gerber's avatar
Jan Gerber committed
802
        if (this->sample_rate==-1) {
803
804
            this->sample_rate = aenc->sample_rate;
        }
Jan Gerber's avatar
Jan Gerber committed
805

Jan Gerber's avatar
Jan Gerber committed
806
807
        if (this->no_upscaling) {
            if (this->sample_rate > aenc->sample_rate)
808
                this->sample_rate = aenc->sample_rate;
Jan Gerber's avatar
Jan Gerber committed
809
            if (this->channels > aenc->channels)
810
811
812
                this->channels = aenc->channels;
        }

Jan Gerber's avatar
Jan Gerber committed
813
        if (acodec != NULL && avcodec_open (aenc, acodec) >= 0) {
814
815
816
            if (this->sample_rate != aenc->sample_rate
                || this->channels != aenc->channels
                || aenc->sample_fmt != SAMPLE_FMT_S16) {
817
818
819
820
821
822
823
824
                // values take from libavcodec/resample.c
                this->audio_resample_ctx = av_audio_resample_init(this->channels,    aenc->channels,
                                                                  this->sample_rate, aenc->sample_rate,
                                                                  SAMPLE_FMT_S16,    aenc->sample_fmt,
                                                                  16, 10, 0, 0.8);
                if (!this->audio_resample_ctx) {
                    this->channels = aenc->channels;
                }
Jan Gerber's avatar
Jan Gerber committed
825
                if (!info.frontend && this->sample_rate!=aenc->sample_rate)
826
                    fprintf(stderr, "  Resample: %dHz => %dHz\n",aenc->sample_rate,this->sample_rate);
Jan Gerber's avatar
Jan Gerber committed
827
                if (!info.frontend && this->channels!=aenc->channels)
828
                    fprintf(stderr, "  Channels: %d => %d\n",aenc->channels,this->channels);
Jan Gerber's avatar
Jan Gerber committed
829
830
831
832
833
834
835
836
837
            }
            else{
                this->audio_resample_ctx=NULL;
            }
        }
        else{
            this->audio_index = -1;
        }
    }
838

839
840
841
    for (i = 0; i < this->context->nb_streams; i++) {
      subtitles_enabled[i] = 0;
      subtitles_opened[i] = 0;
842
#ifdef HAVE_KATE
843
844
845
846
847
848
849
850
      if (!this->disable_subtitles) {
        AVStream *stream = this->context->streams[i];
        AVCodecContext *enc = stream->codec;
        if (enc->codec_type == CODEC_TYPE_SUBTITLE) {
          AVCodec *codec = avcodec_find_decoder (enc->codec_id);
          if (codec && avcodec_open (enc, codec) >= 0) {
            subtitles_opened[i] = 1;
          }
851
          if (is_supported_subtitle_stream(this, i)) {
852
853
854
            subtitles_enabled[i] = 1;
            add_subtitles_stream(this, i, find_language_for_subtitle_stream(stream), NULL);
          }
Jan Gerber's avatar
Jan Gerber committed
855
          else if(!info.frontend) {
856
857
858
859
            fprintf(stderr,"Subtitle stream %d codec not supported, ignored\n", i);
          }
        }
      }
860
#endif
861
862
    }

863
#ifdef HAVE_KATE
864
865
866
    for (i=0; i<this->n_kate_streams; ++i) {
        ff2theora_kate_stream *ks=this->kate_streams+i;
        if (ks->stream_index >= 0) {
867
#ifdef DEBUG
868
869
            printf("Muxing Kate stream %d from input stream %d\n",
                i,ks->stream_index);
870
#endif
871
872
873
874
            if (!this->disable_subtitles) {
              info.with_kate=1;
            }
        }
Jan Gerber's avatar
Jan Gerber committed
875
        else if (load_subtitles(ks,this->ignore_non_utf8,info.frontend)>0) {
876
#ifdef DEBUG
877
878
879
880
            printf("Muxing Kate stream %d from %s as %s %s\n",
                i,ks->filename,
                ks->subtitles_language[0]?ks->subtitles_language:"<unknown language>",
                ks->subtitles_category[0]?ks->subtitles_category:"SUB");
881
#endif
882
883
884
885
886
887
888
889
890
        }
        else {
            if (i!=this->n_kate_streams) {
            memmove(this->kate_streams+i,this->kate_streams+i+1,(this->n_kate_streams-i-1)*sizeof(ff2theora_kate_stream));
            --this->n_kate_streams;
            --i;
          }
        }
    }
891
#endif
892
893
894

    oggmux_setup_kate_streams(&info, this->n_kate_streams);

Jan Gerber's avatar
Jan Gerber committed
895
    if (this->video_index >= 0 || this->audio_index >= 0) {
Jan Gerber's avatar
Jan Gerber committed
896
        AVFrame *frame=NULL;
897
        AVFrame *frame_p=NULL;
Jan Gerber's avatar
Jan Gerber committed
898
        AVFrame *output=NULL;
899
900
        AVFrame *output_p=NULL;
        AVFrame *output_tmp_p=NULL;
Jan Gerber's avatar
Jan Gerber committed
901
        AVFrame *output_tmp=NULL;
902
        AVFrame *output_resized_p=NULL;
Jan Gerber's avatar
Jan Gerber committed
903
        AVFrame *output_resized=NULL;
904
        AVFrame *output_buffered_p=NULL;
Jan Gerber's avatar
Jan Gerber committed
905
        AVFrame *output_buffered=NULL;
906
907
        AVFrame *output_cropped_p=NULL;
        AVFrame *output_cropped=NULL;
Jan Gerber's avatar
Jan Gerber committed
908
909
        AVFrame *output_padded_p=NULL;
        AVFrame *output_padded=NULL;
Jan Gerber's avatar
Jan Gerber committed
910

Jan Gerber's avatar
Jan Gerber committed
911
        AVPacket pkt;
Jan Gerber's avatar
Jan Gerber committed
912
        AVPacket avpkt;
Jan Gerber's avatar
Jan Gerber committed
913
914
915
        int len1;
        int got_picture;
        int first = 1;
916
        int audio_eos = 0, video_eos = 0, audio_done = 0, video_done = 0;
Jan Gerber's avatar
Jan Gerber committed
917
        int ret;
918
919
        int16_t *audio_buf=av_malloc(4*AVCODEC_MAX_AUDIO_FRAME_SIZE);
        int16_t *resampled=av_malloc(4*AVCODEC_MAX_AUDIO_FRAME_SIZE);
Jan Gerber's avatar
Jan Gerber committed
920
        int16_t *audio_p=NULL;
921
        int no_frames;
922
        int no_samples;
Jan Gerber's avatar
Jan Gerber committed
923

Jan Gerber's avatar
Jan Gerber committed
924
        double framerate_add = 0;
925
        double framerate_tmpcount = 0;
Jan Gerber's avatar
Jan Gerber committed
926

Jan Gerber's avatar
Jan Gerber committed
927
        if (this->video_index >= 0)
Jan Gerber's avatar
Jan Gerber committed
928
929
930
            info.audio_only=0;
        else
            info.audio_only=1;
Jan Gerber's avatar
Jan Gerber committed
931

Jan Gerber's avatar
Jan Gerber committed
932
        if (this->audio_index>=0)
Jan Gerber's avatar
Jan Gerber committed
933
934
935
            info.video_only=0;
        else
            info.video_only=1;
Jan Gerber's avatar
Jan Gerber committed
936

937
938
939
940
941
        if(info.audio_only)
            video_done = 1;
        if(info.video_only)
            audio_done = 1;

Jan Gerber's avatar
Jan Gerber committed
942
        if (!info.audio_only) {
943
            frame_p = frame = frame_alloc(vstream->codec->pix_fmt,
944
                            vstream->codec->width,vstream->codec->height);
945
            output_tmp_p = output_tmp = frame_alloc(this->pix_fmt,
946
                            vstream->codec->width, vstream->codec->height);
947
            output_p = output = frame_alloc(this->pix_fmt,
948
                            vstream->codec->width,vstream->codec->height);
949
            output_resized_p = output_resized = frame_alloc(this->pix_fmt,
Jan Gerber's avatar
Jan Gerber committed
950
                            this->picture_width, this->picture_height);
951
952
953
            output_cropped_p = output_cropped = frame_alloc(this->pix_fmt,
                            vstream->codec->width-this->frame_leftBand,
                            vstream->codec->height-this->frame_topBand);
954
            output_buffered_p = output_buffered = frame_alloc(this->pix_fmt,
Jan Gerber's avatar
Jan Gerber committed
955
                            this->frame_width, this->frame_height);
Jan Gerber's avatar
Jan Gerber committed
956
957
            output_padded_p = output_padded = frame_alloc(this->pix_fmt,
                            this->frame_width, this->frame_height);
Jan Gerber's avatar
Jan Gerber committed
958
959
960

            /* video settings here */
            /* config file? commandline options? v2v presets? */
Jan Gerber's avatar
Jan Gerber committed
961

Jan Gerber's avatar
Jan Gerber committed
962
            th_info_init(&info.ti);
Jan Gerber's avatar
Jan Gerber committed
963

Jan Gerber's avatar
Jan Gerber committed
964
965
966
967
968
969
970
971
            //encoded size
            info.ti.frame_width = this->frame_width;
            info.ti.frame_height = this->frame_height;
            //displayed size
            info.ti.pic_width = this->picture_width;
            info.ti.pic_height = this->picture_height;
            info.ti.pic_x = this->frame_x_offset;
            info.ti.pic_y = this->frame_y_offset;
972
973
974
            if (this->framerate_new.num > 0) {
                // new framerate is interger only right now,
                // so denominator is always 1
Jan Gerber's avatar
Jan Gerber committed
975
976
                this->framerate.num = this->framerate_new.num;
                this->framerate.den = this->framerate_new.den;
Jan Gerber's avatar
Jan Gerber committed
977
978
            }
            else {
Jan Gerber's avatar
Jan Gerber committed
979
980
                this->framerate.num = vstream_fps.num;
                this->framerate.den = vstream_fps.den;
Jan Gerber's avatar
Jan Gerber committed
981
            }
Jan Gerber's avatar
Jan Gerber committed
982
983
            info.ti.fps_numerator = this->framerate.num;
            info.ti.fps_denominator = this->framerate.den;
Jan Gerber's avatar
Jan Gerber committed
984
985
986
            /* this is pixel aspect ratio */
            info.ti.aspect_numerator=this->aspect_numerator;
            info.ti.aspect_denominator=this->aspect_denominator;
Jan Gerber's avatar
Jan Gerber committed
987
            /*
Jan Gerber's avatar
Jan Gerber committed
988
989
            // FIXME: is all input material with fps==25 OC_CS_ITU_REC_470BG?
            // guess not, commandline option to select colorspace would be the best.
Jan Gerber's avatar
Jan Gerber committed
990
            if ((this->fps-25)<1)
Jan Gerber's avatar
Jan Gerber committed
991
                info.ti.colorspace = TH_CS_ITU_REC_470BG;
Jan Gerber's avatar
Jan Gerber committed
992
            else if (abs(this->fps-30)<1)
Jan Gerber's avatar
Jan Gerber committed
993
                info.ti.colorspace = TH_CS_ITU_REC_470M;
Jan Gerber's avatar
Jan Gerber committed
994
            else
Jan Gerber's avatar
Jan Gerber committed
995
996
997
998
999
1000
            */
            info.ti.colorspace = TH_CS_UNSPECIFIED;

            /*Account for the Ogg page overhead.
              This is 1 byte per 255 for lacing values, plus 26 bytes per 4096 bytes for
               the page header, plus approximately 1/2 byte per packet (not accounted for
For faster browsing, not all history is shown. View entire blame