~ubuntu-branches/ubuntu/karmic/dvd95/karmic

« back to all changes in this revision

Viewing changes to src/dvd2avi.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2009-05-03 23:58:59 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090503235859-hbax2t4i7ubfxzks
Tags: 1.5p0-0ubuntu1
* New upstream release.
* debian/rules:
  - Add get-orig-source target to get a repacked tarball, we
    need to remove the debian dir provided by upstream.
  - Now locales are installed in the right path, no need to move
    usr/local/share/locale to usr/share/.
* debian/control:
  - Build-Depends on intltool, mplayer, mencoder, ffmpeg.
  - Depends on mplayer, mencoder, ffmpeg.
  - Update binary package description.
  - Bump-up Standards-Version.
* debian/copyright:
  - Use © instead of old (C) symbol.
  - Update license information.
  - On debian systems:
    - LGPL-2 can be found in /usr/share/common-licenses/LGPL-2.
    - GPL-3 can be found in /usr/share/common-licenses/GPL-3.
* debian/patches/00list:
  - Listed patch file names shouldn't end with .dpatch extension.
* Add 02_fix_configure_libdvdread.dpatch patch to fix FTBFS due to a
  libdvdread version check in configure script.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*==============================================================================
 
2
 
 
3
FICHIER     : [dvdbackup.c]
 
4
 
 
5
DATE        : 2006/01/0005 20:56:20
 
6
 
 
7
CREATEUR    : [Linux!jef]
 
8
 
 
9
COMMENTAIRE :
 
10
 * encoding     UTF8 !-UTF8-!
 
11
                Released under GPL license, see gnu.org
 
12
================================================================================
 
13
 
 
14
==============================================================================*/
 
15
#define __USE_LARGEFILE64
 
16
#define _LARGEFILE64_SOURCE
 
17
#ifdef HAVE_CONFIG_H
 
18
#  include <config.h>
 
19
#endif
 
20
#include <stdio.h>
 
21
#include <stdlib.h>
 
22
#include <sys/time.h>
 
23
#include <sys/stat.h>
 
24
#include <alloca.h>
 
25
#include <math.h>
 
26
 
 
27
#include <gnome.h>
 
28
 
 
29
#ifdef __APPLE__
 
30
/* fopen is 64-bit aware on Mac OS X */
 
31
#define fopen64(A,B) fopen(A,B)
 
32
#endif
 
33
 
 
34
#define CTEST(x)                /***/
 
35
 
 
36
#include "support.h"
 
37
 
 
38
#include "const.h"
 
39
#include "dvdformat.h"
 
40
#include "dvdinfo.h"
 
41
#include "message.h"
 
42
#include "gconfig.h"
 
43
#include "tampon.h"
 
44
#include "interface.h"
 
45
#include "globals.h"
 
46
#include "systools.h"
 
47
#include "avancement.h"
 
48
#include "uitools.h"
 
49
#include "dvdtools.h"
 
50
#include "dvdcopy.h"
 
51
#include "ifo.h"
 
52
#include "bswap.h"
 
53
#include "vaporize.h"
 
54
#include "ac.h"
 
55
#include "dvdcell.h"
 
56
#include "../dvdauthor/libauthor.h"
 
57
#include "vapcontext.h"
 
58
#include "mpeg2dec.h"
 
59
#include "profile.h"
 
60
 
 
61
static char TitreDvd[128];
 
62
 
 
63
static CellArray_t CellArray;
 
64
static TitleArray_t TitleArray;
 
65
 
 
66
static int CurVTS;
 
67
static FILE * OutFpVideo;       /* Video file pointer */
 
68
static long long OutSize;
 
69
static long long TotalSize;
 
70
 
 
71
static int CurVOB;
 
72
static uint32_t Position;
 
73
 
 
74
static unsigned char TempBuf[DVD_VIDEO_LB_LEN * 2];
 
75
static int TempSize = 0;
 
76
 
 
77
typedef struct {
 
78
        char *  vobFile;
 
79
        char *  aviFile;
 
80
        char *  logFile;
 
81
        int     bitrate;
 
82
        char *  cropParam;
 
83
        int     scaleX;
 
84
        int     scaleY;
 
85
        double  aspect;
 
86
} EncodingInfos_t;
 
87
 
 
88
 
 
89
/*@$#[dvd2avi.c] static proto. AutoProtoSigV1.1. date: 2009/01/28 21:19:17 */
 
90
#include "proto.h"
 
91
#ifdef __cplusplus
 
92
extern "C" {
 
93
#endif
 
94
/* dvd2avi.c */
 
95
static int Output PROTO((unsigned char *buffer, int len, char *targetDir));
 
96
static void MakeRoom PROTO((VapContext_t *c, int size));
 
97
static uint32_t _FindNextVobu PROTO((VapContext_t *c));
 
98
static int Readin PROTO((void *parm, unsigned char *buffer, int size));
 
99
static int OutputFlux PROTO((void *parm, unsigned char *buffer, int size));
 
100
static int CopyCell PROTO((Cell_t *c, char *targetDir));
 
101
static void FreeAll PROTO((void));
 
102
static int _readline PROTO((FILE *fp, char *line, int size));
 
103
static double GetAspectRatio PROTO((int noPisteVideo));
 
104
static void GetPictureSizes PROTO((int noPisteVideo, Profile_t *p, int cx, int cy, int *sx, int *sy, int bitrate));
 
105
static int CropDetection PROTO((char *iFile, char *cropParam));
 
106
static char *ComputeCmdLine PROTO((Profile_t *profile, EncodingInfos_t *infos, int passNo));
 
107
static long long GetVobSize PROTO((int noPisteVideo));
 
108
#ifdef __cplusplus
 
109
}
 
110
#endif
 
111
/*@$% end of AutoProtoSigV1.1 (Dont remove this line) [-I ../include]*/
 
112
 
 
113
/*------------------------------------------------------------------------------
 
114
        OUTPUT-
 
115
Linux!jef 2006/01/03 21:05:50
 
116
------------------------------------------------------------------------------*/
 
117
 
 
118
static int Output( buffer, len, targetDir )
 
119
unsigned char * buffer;
 
120
int len;
 
121
char * targetDir;
 
122
{
 
123
        unsigned char * cBuff;
 
124
 
 
125
        if( !TempSize && len == DVD_VIDEO_LB_LEN ) {
 
126
                TempSize = len;
 
127
                cBuff = buffer;
 
128
        }
 
129
        else {
 
130
//!! fprintf(stderr,"Output: len %d TempSize: %d\n", len, TempSize );
 
131
                tc_memcpy( TempBuf + TempSize, buffer, len );
 
132
                TempSize += len;
 
133
                cBuff = TempBuf;
 
134
        }
 
135
        if( TempSize >= DVD_VIDEO_LB_LEN ) {
 
136
 
 
137
                if( !isNavPack( cBuff ) ) {
 
138
                        Mpeg2Demux( cBuff, DVD_VIDEO_LB_LEN );
 
139
                }
 
140
                if( fwrite( cBuff, 1, DVD_VIDEO_LB_LEN, OutFpVideo ) != DVD_VIDEO_LB_LEN )      return( -1 );
 
141
                OutSize += DVD_VIDEO_LB_LEN;
 
142
                TotalSize += DVD_VIDEO_LB_LEN;
 
143
                SetTotalSize( TotalSize );
 
144
                Position++;
 
145
                TempSize -= DVD_VIDEO_LB_LEN;
 
146
                if( TempSize > 0 )      tc_memcpy( cBuff, cBuff + DVD_VIDEO_LB_LEN, TempSize );
 
147
        }
 
148
        return( 0 );
 
149
}
 
150
/*------------------------------------------------------------------------------
 
151
        MAKEROOM-
 
152
Linux!jef 2006/01/24 22:46:53
 
153
------------------------------------------------------------------------------*/
 
154
 
 
155
static void MakeRoom( VapContext_t * c, int size )
 
156
{
 
157
//      DBG('b',fprintf(stderr,"%s: size: %d\n", __FUNCTION__, size ););
 
158
 
 
159
        if( c->bufASize < (c->bufSize + size) ) {
 
160
                if( c->bufPtr != c->buf ) {
 
161
                        memmove( c->buf, c->bufPtr, c->bufSize );
 
162
                        c->bufPtr = c->buf;
 
163
                }
 
164
                c->bufASize = c->bufSize + size;
 
165
                c->buf = realloc( c->buf, c->bufASize );
 
166
                c->bufPtr = c->buf;
 
167
        }
 
168
        if( !c->bufSize ) {
 
169
                c->bufPtr = c->buf;
 
170
                return;
 
171
        }
 
172
}
 
173
 
 
174
/*------------------------------------------------------------------------------
 
175
        _FINDNEXTVOBU-
 
176
Linux!jef 2007/08/16 01:37:18
 
177
------------------------------------------------------------------------------*/
 
178
 
 
179
static uint32_t _FindNextVobu( c )
 
180
VapContext_t * c;
 
181
{
 
182
        vobu_admap_t * vobu_admap;
 
183
        uint32_t length, i;
 
184
 
 
185
        vobu_admap = c->cell->ifo->vts_vobu_admap;
 
186
        length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE;
 
187
 
 
188
        for( i = 0; i < length/sizeof(uint32_t); i++) {
 
189
// DBG('b',fprintf(stderr,"%s: vobu at sector: %d\n", __FUNCTION__, vobu_admap->vobu_start_sectors[i] ););
 
190
/* Vobu adress map seems to be ordered */
 
191
                if( vobu_admap->vobu_start_sectors[i] > c->sector) {
 
192
                        DBG('b',fprintf(stderr,"%s: returning next vobu at sector: %d\n", __FUNCTION__, vobu_admap->vobu_start_sectors[i] ););
 
193
                        return( vobu_admap->vobu_start_sectors[i] );
 
194
                }
 
195
//              if( vobu_admap->vobu_start_sectors[i] == c->sector) {
 
196
//                      return( vobu_admap->vobu_start_sectors[i+1] );
 
197
//              }
 
198
        }
 
199
        DBG('b',fprintf(stderr,"%s: nextvobu notfound for sector: %d\n", __FUNCTION__, c->sector ););
 
200
        return( SRI_END_OF_CELL );
 
201
}
 
202
 
 
203
/*------------------------------------------------------------------------------
 
204
        READIN-
 
205
Linux!jef 2006/01/24 22:28:46
 
206
------------------------------------------------------------------------------*/
 
207
 
 
208
static int Readin( void * parm, unsigned char * buffer, int size )
 
209
{
 
210
        VapContext_t * c = (VapContext_t *) parm;
 
211
        int readed = 0;
 
212
        int len;
 
213
        dsi_t   dsi_pack;
 
214
        uint32_t nsectors;
 
215
        int badNavPack = 0;
 
216
 
 
217
//      DBG('b',fprintf(stderr,"%s: size: %d inBuf: %d\n", __FUNCTION__, size, c->bufSize ););
 
218
 
 
219
        if( c->bufSize ) {
 
220
                len = MyMin( size, c->bufSize );
 
221
 
 
222
                tc_memcpy( buffer, c->bufPtr, len );
 
223
                buffer += len;
 
224
                size -= len;
 
225
                c->bufPtr += len;
 
226
                c->bufSize -= len;
 
227
                readed += len;
 
228
        }
 
229
        if( !size ) {
 
230
//              DBG('b',fprintf(stderr,"%s: readed: %d\n", __FUNCTION__, readed ););
 
231
                return( readed );
 
232
        }
 
233
 
 
234
        if( c->dsi_next_vobu == SRI_END_OF_CELL ) {
 
235
                if( readed )    return( readed );
 
236
 
 
237
//              DBG('b',fprintf(stderr,"%s: EOF\n", __FUNCTION__ ););
 
238
                return( 0 ); /* EOF */
 
239
        }
 
240
 
 
241
/* read nav pack */
 
242
        MakeRoom( c, DVD_VIDEO_LB_LEN );
 
243
        len = MyDVDRead1Block( c->file_handle, c->sector, c->bufPtr );
 
244
        if( len == -1 ) return( -1 );
 
245
/* parse contained DSI pack */
 
246
        navRead_DSI( &dsi_pack, c->bufPtr + DSI_START_BYTE );
 
247
        if( len == 0 || dsi_pack.dsi_gi.nv_pck_lbn != c->sector ) {
 
248
                CreateDummyNavPack( c->bufPtr, c->sector );
 
249
                badNavPack = 1;
 
250
                c->dsi_next_vobu = _FindNextVobu( c );
 
251
        }
 
252
 
 
253
        len = DVD_VIDEO_LB_LEN;
 
254
        c->bufSize += len;
 
255
 
 
256
        Avancement( len );
 
257
        if( AvancementUi( NULL ) < 0 )  return( -1 );
 
258
        if( badNavPack ) {
 
259
                MakeRoom( c, 1 * DVD_VIDEO_LB_LEN );
 
260
                CreateDummyPack( c->bufPtr + DVD_VIDEO_LB_LEN );
 
261
                nsectors = 1;
 
262
        }
 
263
        else {
 
264
                int i;
 
265
                unsigned char * cBuff;
 
266
 
 
267
                nsectors  = dsi_pack.dsi_gi.vobu_ea;
 
268
                if( !nsectors ) { /* Protected dvd ? */
 
269
                        DBG('b',fprintf(stderr,"%s: no sectors in DSI !\n", __FUNCTION__););
 
270
                        return( 0 ); /* EOF */
 
271
                }
 
272
                c->dsi_next_vobu = dsi_pack.vobu_sri.next_vobu;
 
273
 
 
274
                MakeRoom( c, nsectors*DVD_VIDEO_LB_LEN );
 
275
                cBuff = c->bufPtr + DVD_VIDEO_LB_LEN;
 
276
/* read VOBU */
 
277
                for( i = 0; i < nsectors; i++ ) {
 
278
                        len = MyDVDRead1Block( c->file_handle, c->sector + 1 + i, cBuff );
 
279
// fprintf(stderr,"PACK: MyDVDRead1Block(%d)=%d\n", c->sector+1+i, len );
 
280
                        if( len == -1 ) return( -1 );
 
281
                        if( len == 0 ) {
 
282
                                CreateDummyPack( cBuff );
 
283
                                nsectors = 1;
 
284
                                break;
 
285
                        }
 
286
                        cBuff += DVD_VIDEO_LB_LEN;
 
287
                }
 
288
        }
 
289
        len = nsectors * DVD_VIDEO_LB_LEN;
 
290
        c->bufSize += len;
 
291
 
 
292
        Avancement( len );
 
293
        if( AvancementUi( NULL ) < 0 )  return( -1 );
 
294
        if( badNavPack ) {
 
295
                c->sector = c->dsi_next_vobu;
 
296
                c->dsi_next_vobu  = 0;
 
297
        }
 
298
        else
 
299
                c->sector += (c->dsi_next_vobu & 0x7fffffff);
 
300
 
 
301
        return( readed + Readin( parm, buffer, size ) );
 
302
}
 
303
 
 
304
/*------------------------------------------------------------------------------
 
305
        OUTPUTFLUX-
 
306
Linux!jef 2006/01/24 23:07:28
 
307
------------------------------------------------------------------------------*/
 
308
 
 
309
static int OutputFlux( void * parm, unsigned char * buffer, int size )
 
310
{
 
311
        VapContext_t * c = (VapContext_t *) parm;
 
312
        int writen = 0;
 
313
 
 
314
//      DBG('b',fprintf(stderr,"%s: size: %d\n", __FUNCTION__, size ););
 
315
        while( size > 0 ) {
 
316
                int len = MyMin( size, DVD_VIDEO_LB_LEN );
 
317
 
 
318
                if( Output( buffer, len, c->targetDir ) < 0 ) {
 
319
                        return( -1 );
 
320
                }
 
321
                buffer += len;
 
322
                size -= len;
 
323
                writen += len;
 
324
        }
 
325
        return( writen );
 
326
}
 
327
 
 
328
/*------------------------------------------------------------------------------
 
329
        COPYCELL-
 
330
Linux!jef 2005/12/28 22:01:08
 
331
------------------------------------------------------------------------------*/
 
332
 
 
333
static int CopyCell( Cell_t * c, char * targetDir )
 
334
{
 
335
        uint32_t size;
 
336
        dvd_file_t * file_handle;
 
337
        VapContext_t vc;
 
338
        long long lSize;
 
339
        int ret;
 
340
 
 
341
        if( !c->selected )      return( 0 );
 
342
 
 
343
        DBG('b',fprintf(stderr,"%s: startSector: %u lastSector: %u vts: %d\n", __FUNCTION__, c->startSector, c->lastSector, c->vts ););
 
344
 
 
345
        size = c->lastSector - c->startSector;
 
346
        DisplayAvancement( _("Copie de la cellule %d (%d secteurs)\n"), c->chapter + 1, size);
 
347
        InitAvancement( size );
 
348
        file_handle = DVDOpenFile( Dvd, c->vts, DVD_READ_TITLE_VOBS);
 
349
        if( !file_handle ) {
 
350
                return( -1 );
 
351
        }
 
352
        memset( &vc, 0, sizeof(vc));
 
353
/* Initialize Vaporize context */
 
354
        vc.file_handle = file_handle;
 
355
        vc.sector = c->startSector;
 
356
        vc.cell = c;
 
357
        vc.targetDir = targetDir;
 
358
        lSize = (long long) size * (long long) DVD_VIDEO_LB_LEN;
 
359
        ret = Vaporize( lSize, &vc );
 
360
 
 
361
        if( vc.buf ) {
 
362
                free( vc.buf );
 
363
        }
 
364
        DVDCloseFile( file_handle );
 
365
        c->done = 1;
 
366
        return( ret );
 
367
}
 
368
 
 
369
/*------------------------------------------------------------------------------
 
370
        FREEALL-
 
371
Linux!jef 2006/01/16 22:10:25
 
372
------------------------------------------------------------------------------*/
 
373
 
 
374
static void FreeAll()
 
375
{
 
376
        int i;
 
377
 
 
378
        if( TitleArray.nbTitles ) {
 
379
                for( i = 0; i < TitleArray.nbTitles; i++ ) {
 
380
                        FreeCellArray( &TitleArray.titles[i].ca );
 
381
                }
 
382
                free( TitleArray.titles );
 
383
                TitleArray.titles = NULL;
 
384
                TitleArray.nbTitles = 0;
 
385
        }
 
386
        FreeCellArray( &CellArray );
 
387
}
 
388
/*------------------------------------------------------------------------------
 
389
        _READLINE-
 
390
Linux!jef 2006/02/16 22:58:23
 
391
------------------------------------------------------------------------------*/
 
392
 
 
393
static int _readline( FILE * fp, char * line, int size )
 
394
{
 
395
        int readed = 0;
 
396
 
 
397
        size--;
 
398
        while( size ) {
 
399
                int c = fgetc( fp );
 
400
 
 
401
                if( c == EOF )  break;
 
402
                if( c == '\r' ) c = '\n';
 
403
                *line++ = (char)c;
 
404
                readed++;
 
405
                size--;
 
406
                if( c == '\n' ) break;
 
407
        }
 
408
        *line = 0;
 
409
        return( readed );
 
410
}
 
411
/*------------------------------------------------------------------------------
 
412
        EXECUTEFFMPEG-
 
413
Linux!jef 2005/12/20 22:17:17
 
414
------------------------------------------------------------------------------*/
 
415
 
 
416
int ExecuteFfmpeg( char * sysCmd, int duree )
 
417
{
 
418
        FILE * fp;
 
419
        char line[1024];
 
420
        int res = 0;
 
421
        double lPct = -1;
 
422
 
 
423
        InitAvancement(0);
 
424
/* re-direct stderr */
 
425
        strcat( sysCmd, " 2>&1" );
 
426
        DBG('c',fprintf(stderr,"%s: executing (%s) duree: %d\n", __FUNCTION__, sysCmd, duree ););
 
427
        fp = my_popen( sysCmd, "r" );
 
428
        if( !fp )        return( -1 );
 
429
        setbuf( fp, NULL );
 
430
        while( 1 )
 
431
        {
 
432
                char * p;
 
433
 
 
434
                if( !_readline( fp, line, sizeof(line)))        break;
 
435
                if( !*line )    continue;
 
436
// fprintf(stderr,"line(%s)\n", line );
 
437
                p = strstr( line, "time=" );
 
438
                if( p ) {
 
439
                        double where;
 
440
                        double pct;
 
441
 
 
442
                        p += 5;
 
443
                        where = atof( p );
 
444
 
 
445
                        pct = ( where ) / (double) duree;;
 
446
// fprintf(stderr,"%f/%d = %f%%\n", where, duree, pct );
 
447
                        if( pct > lPct ) {
 
448
                                if( AvancementUi2( pct ) < 0 ) { res = -1; break; }
 
449
                                lPct = pct;
 
450
                        }
 
451
                        else
 
452
                                GtkFlush();
 
453
                }
 
454
        }
 
455
        res = my_pclose( fp );
 
456
        DBG('c',fprintf(stderr,"%s: result= %d\n", __FUNCTION__, res ););
 
457
        if( res != 0 )  res = -1;
 
458
        return( res );
 
459
}
 
460
/*------------------------------------------------------------------------------
 
461
        EXECUTEMENCODER-
 
462
Linux!jef 2005/12/20 22:17:17
 
463
------------------------------------------------------------------------------*/
 
464
 
 
465
int ExecuteMencoder( char * sysCmd, int duree )
 
466
{
 
467
        FILE * fp;
 
468
        char line[1024];
 
469
        int res = 0;
 
470
        double lPct = -1;
 
471
 
 
472
        InitAvancement(0);
 
473
/* re-direct stderr */
 
474
        strcat( sysCmd, " 2>&1" );
 
475
        DBG('c',fprintf(stderr,"%s: executing (%s) duree: %d\n", __FUNCTION__, sysCmd, duree ););
 
476
        fp = my_popen( sysCmd, "r" );
 
477
        if( !fp )        return( -1 );
 
478
        setbuf( fp, NULL );
 
479
        while( 1 )
 
480
        {
 
481
                char * p;
 
482
 
 
483
                if( !_readline( fp, line, sizeof(line)))        break;
 
484
                if( !*line )    continue;
 
485
// fprintf(stderr,"line(%s)\n", line );
 
486
                p = strstr( line, "Pos:" );
 
487
                if( p ) {
 
488
                        double where;
 
489
                        double pct;
 
490
 
 
491
                        p += 4;
 
492
                        while( *p == ' ' )      p++;
 
493
                        where = atof( p );
 
494
 
 
495
                        pct = ( where ) / (double) duree;;
 
496
// fprintf(stderr,"%f/%d = %f%%\n", where, duree, pct );
 
497
                        if( pct > lPct ) {
 
498
                                if( AvancementUi2( pct ) < 0 ) { res = -1; break; }
 
499
                                lPct = pct;
 
500
                        }
 
501
                        else
 
502
                                GtkFlush();
 
503
                }
 
504
        }
 
505
        res = my_pclose( fp );
 
506
        DBG('c',fprintf(stderr,"%s: result= %d\n", __FUNCTION__, res ););
 
507
        if( res != 0 )  res = -1;
 
508
        return( res );
 
509
}
 
510
/***************************************************************************//**
 
511
 *      GETASPECTRATIO-
 
512
 * @date        2009/01/19 22:11:49
 
513
 * @author      jef-Linux
 
514
 * @brief
 
515
 *      Pas d'explication
 
516
 * @details
 
517
 *      Pas de details
 
518
 * @param[in]   Pas de detail
 
519
 * @param[out]  Pas de detail
 
520
*******************************************************************************/
 
521
 
 
522
static double GetAspectRatio( int noPisteVideo )
 
523
{
 
524
        ifo_handle_t * ifo = Ifo[Ifo_zero->tt_srpt->title[noPisteVideo].title_set_nr];
 
525
        vtsi_mat_t *vtsi_mat = ifo->vtsi_mat;
 
526
        video_attr_t *video_attr;
 
527
        char *aspect_ratio[4] = {"4:3", "16:9", "4:3", "16:9"};
 
528
 
 
529
        video_attr = &vtsi_mat->vts_video_attr;
 
530
 
 
531
        if( *aspect_ratio[video_attr->display_aspect_ratio] == '4' )
 
532
                return( 4.0/3.0 );
 
533
        return( 16.0/9.0 );
 
534
}
 
535
/***************************************************************************//**
 
536
 *      GETPICTURESIZES-
 
537
 * @date        2009/01/20 20:49:21
 
538
 * @author      jef-Linux
 
539
 * @brief
 
540
 *      Pas d'explication
 
541
 * @details
 
542
 *      Pas de details
 
543
 * @param[in]   Pas de detail
 
544
 * @param[out]  Pas de detail
 
545
*******************************************************************************/
 
546
 
 
547
static void GetPictureSizes( int noPisteVideo, Profile_t * p, int cx, int cy, int * sx, int * sy, int bitrate )
 
548
{
 
549
        char *aspect_ratio[4] = {"4:3", "16:9", "4:3", "16:9"};
 
550
        double video_height[4] = { 480, 576, 576, 576 };
 
551
        double video_width[4]  = { 720, 704, 352, 352};
 
552
        ifo_handle_t * ifo = Ifo[Ifo_zero->tt_srpt->title[noPisteVideo].title_set_nr];
 
553
        vtsi_mat_t *vtsi_mat = ifo->vtsi_mat;
 
554
        video_attr_t *video_attr;
 
555
        double ARa;
 
556
        double PRdvd;
 
557
        double ARc;
 
558
        double resX,resY;
 
559
        double CQ = 0.30;
 
560
 
 
561
        bitrate *= 1000;
 
562
        video_attr = &vtsi_mat->vts_video_attr;
 
563
 
 
564
        if( *aspect_ratio[video_attr->display_aspect_ratio] == '4' ) {
 
565
                ARa = 4.0/3.0;
 
566
                PRdvd = video_width[video_attr->picture_size] / video_height[video_attr->video_format];
 
567
        }
 
568
        else {
 
569
                ARa = 16.0/9.0;
 
570
                PRdvd = video_width[video_attr->picture_size] / video_height[video_attr->video_format];
 
571
        }
 
572
        ARc = ( (double)cx * ( ARa / PRdvd)) / (double)cy;
 
573
        resY = rint(sqrt( (double)bitrate / 25.0 / ARc / CQ ) / 16.0) * 16.0;
 
574
        resX = rint( resY * ARc / 16.0 ) * 16.0;
 
575
/*      Protect orginal sizes if bigger */
 
576
        if( resX >= cx || resY >= cy ) {
 
577
                resX = cx;
 
578
                resY = cy;
 
579
        }
 
580
 
 
581
        DBG( 'b',fprintf(stderr,"%s: ARa=%f\n", __FUNCTION__, ARa ););
 
582
        DBG( 'b',fprintf(stderr,"%s: PRdvd=%f\n", __FUNCTION__, PRdvd ););
 
583
        DBG( 'b',fprintf(stderr,"%s: ARc=%f\n", __FUNCTION__, ARc ););
 
584
        DBG( 'b',fprintf(stderr,"%s: ResX=%f\n", __FUNCTION__, resX ););
 
585
        DBG( 'b',fprintf(stderr,"%s: ResY=%f\n", __FUNCTION__, resY ););
 
586
 
 
587
        *sx = resX;
 
588
        *sy = resY;
 
589
}
 
590
 
 
591
/***************************************************************************//**
 
592
 *      CROPDETECTION-
 
593
 * @date        2009/01/19 22:50:34
 
594
 * @author      jef-Linux
 
595
 * @brief
 
596
 *      Pas d'explication
 
597
 * @details
 
598
 *      Pas de details
 
599
 * @param[in]   Pas de detail
 
600
 * @param[out]  Pas de detail
 
601
*******************************************************************************/
 
602
 
 
603
static int CropDetection( char * iFile, char * cropParam )
 
604
{
 
605
        char sysCmd[1024];
 
606
        FILE * fp;
 
607
        char line[1024];
 
608
        int res = 0;
 
609
        double lPct = -1;
 
610
        int duree = 60;
 
611
        int startPos = 120;
 
612
        int frames = duree * 25;
 
613
 
 
614
        *cropParam = 0;
 
615
        sprintf( sysCmd, "mplayer -vo null -ao null -ss %d -frames %d -nosound -speed 100 -vf cropdetect %s", startPos, frames, iFile );
 
616
        strcat( sysCmd, " 2>&1" );
 
617
        DBG('c',fprintf(stderr,"%s: executing (%s)\n", __FUNCTION__, sysCmd ););
 
618
        fp = my_popen( sysCmd, "r" );
 
619
        if( !fp )        return( -1 );
 
620
        DisplayAvancement( _("Détection des bandes noires\n"));
 
621
        InitAvancement(0);
 
622
        setbuf( fp, NULL );
 
623
        while( 1 )
 
624
        {
 
625
                char * p;
 
626
 
 
627
                if( !_readline( fp, line, sizeof(line)))        break;
 
628
                if( !*line )    continue;
 
629
// fprintf(stderr,"line(%s)\n", line );
 
630
                p = strstr( line, "crop=" );
 
631
                if( p ) {
 
632
                        char * pStart;
 
633
 
 
634
                        p += 5;
 
635
                        pStart = p;
 
636
                        while( *p && *p != ')' )        p++;
 
637
                        if( *p == ')' ) {
 
638
                                *p = 0;
 
639
                                strcpy( cropParam, pStart );
 
640
                        }
 
641
                }
 
642
                p = strstr( line, "V:" );
 
643
                if( p ) {
 
644
                        double where;
 
645
                        double pct;
 
646
 
 
647
                        p += 2;
 
648
                        while( *p == ' ' )      p++;
 
649
                        where = atof( p ) - startPos;
 
650
 
 
651
                        pct = ( where ) / (double) duree;;
 
652
// fprintf(stderr,"(%s) %f/%d = %f%%\n", line,  where, duree, pct );
 
653
                        if( pct >= 0.0 && pct <= 1.0 && pct > lPct ) {
 
654
                                if( AvancementUi2( pct ) < 0 ) { res = -1; break; }
 
655
                                lPct = pct;
 
656
                        }
 
657
                }
 
658
        }
 
659
        res = my_pclose( fp );
 
660
        DBG('c',fprintf(stderr,"%s: result= %d\n", __FUNCTION__, res ););
 
661
        if( res != 0 )  res = -1;
 
662
        return( res );
 
663
}
 
664
/***************************************************************************//**
 
665
 *      COMPUTECMDLINE-
 
666
 * @date        2009/01/19 21:47:44
 
667
 * @author      jef-Linux
 
668
 * @brief
 
669
 *      Pas d'explication
 
670
 * @details
 
671
 *      Pas de details
 
672
 * @param[in]   Pas de detail
 
673
 * @param[out]  Pas de detail
 
674
*******************************************************************************/
 
675
 
 
676
static char * ComputeCmdLine( Profile_t * profile, EncodingInfos_t * infos, int passNo )
 
677
{
 
678
        char * oLine = malloc( 10240 ); /* KK */
 
679
        char * p = oLine;
 
680
        char * iLine;
 
681
 
 
682
        if( passNo == 1 )
 
683
                iLine = profile->pass1Opt;
 
684
        else
 
685
                iLine = profile->pass2Opt;
 
686
 
 
687
        strcpy( p, profile->encTool );
 
688
        strcat( p, " " );
 
689
        p += strlen( p );
 
690
 
 
691
        while( *iLine ) {
 
692
                if( *iLine == '%' ) {
 
693
                        switch( iLine[1] ) {
 
694
                                case 'b' :
 
695
                                        sprintf( p, "%d", infos->bitrate );
 
696
                                        p += strlen( p );
 
697
                                        break;
 
698
                                case 'a' :
 
699
                                        sprintf( p, "%.5f", infos->aspect );
 
700
                                        p += strlen( p );
 
701
                                        break;
 
702
                                case 'i' :
 
703
                                        strcpy( p, infos->vobFile );
 
704
                                        p += strlen( p );
 
705
                                        break;
 
706
                                case 'o' :
 
707
                                        strcpy( p, infos->aviFile );
 
708
                                        p += strlen( p );
 
709
                                        break;
 
710
                                case 'p' :
 
711
                                        strcpy( p, infos->logFile );
 
712
                                        p += strlen( p );
 
713
                                        break;
 
714
                                case 'c' :
 
715
                                        strcpy( p, infos->cropParam );
 
716
                                        p += strlen( p );
 
717
                                        break;
 
718
                                case 'u' :
 
719
                                        sprintf( p, "%d", GetNumCpu() );
 
720
                                        p += strlen( p );
 
721
                                        break;
 
722
                                case 'x' :
 
723
                                        sprintf( p, "%d", infos->scaleX );
 
724
                                        p += strlen( p );
 
725
                                        break;
 
726
                                case 'y' :
 
727
                                        sprintf( p, "%d", infos->scaleY );
 
728
                                        p += strlen( p );
 
729
                                        break;
 
730
                        }
 
731
                        iLine++;
 
732
                }
 
733
                else
 
734
                        *p++ = *iLine;
 
735
                iLine++;
 
736
        }
 
737
        *p = 0;
 
738
        return( oLine );
 
739
}
 
740
/***************************************************************************//**
 
741
 *      GETVOBSIZE-
 
742
 * @date        2009/01/21 20:53:40
 
743
 * @author      jef-Linux
 
744
 * @brief
 
745
 *      Pas d'explication
 
746
 * @details
 
747
 *      Pas de details
 
748
 * @param[in]   Pas de detail
 
749
 * @param[out]  Pas de detail
 
750
*******************************************************************************/
 
751
 
 
752
static long long GetVobSize( int noPisteVideo )
 
753
{
 
754
        int totalSectors = 0;
 
755
        int i;
 
756
 
 
757
        for( i = 0; i < CellArray.nbCells; i++ ) {
 
758
                Cell_t * c = CellArray.cells + i;
 
759
 
 
760
                if( c->selected )       totalSectors += SECTOR_SZ(c);
 
761
        }
 
762
        return( (long long)totalSectors * (long long) DVD_BLOCK_LEN );
 
763
}
 
764
 
 
765
 
 
766
/*------------------------------------------------------------------------------
 
767
        COPYDVD-
 
768
Linux!jef 2005/12/12 22:36:50
 
769
------------------------------------------------------------------------------*/
 
770
 
 
771
int DvdToAvi( GtkWidget * forme, int noPisteVideo, AudioMap_t * audioMap, SubMap_t * subMap, int format )
 
772
{
 
773
        GtkWidget * item;
 
774
        char * tmpDir = ConfigGetString( KEY_TEMP, "/tmp" );
 
775
        char * isoDir = ConfigGetString( KEY_ISODIR, "/tmp" );
 
776
        int lastCellF = ConfigGetInt( KEY_GENERIQUE, 0 );
 
777
        char targetDir[512];
 
778
        char vobFile[1024];
 
779
        char aviFile[1024];
 
780
        char logFile[1024];
 
781
        int i;
 
782
        char injectionFile[100];
 
783
        const gchar * text;
 
784
        int ret = 0;
 
785
        int res;
 
786
        int nbSteps;
 
787
        int duree;
 
788
        Profile_t * profile = GetProfile( format );
 
789
        int vobOk = 0;
 
790
        int aviDone = 0;
 
791
        long long fsize;
 
792
        int nbAudio = 0;
 
793
 
 
794
        DBG('b',fprintf(stderr,"%s: format: %d\n", __FUNCTION__, format ););
 
795
        if( !profile )  return(-1);
 
796
 
 
797
/* Verify we have enought free space to extract */
 
798
        fsize = FsFree( tmpDir ) - GetVobSize( noPisteVideo );
 
799
        if( fsize < 0 ) {
 
800
                PlayError();
 
801
                MessageBoxError( _("Pas assez de place sur %s\nIl manque %s octets !"), tmpDir, LLSize2Giga( -fsize ) );
 
802
                return( -1 );
 
803
        }
 
804
/* Verify we have enought free space to encode */
 
805
        fsize = FsFree( isoDir ) - profile->fileSize;
 
806
        if( fsize < 0 ) {
 
807
                PlayError();
 
808
                MessageBoxError( _("Pas assez de place sur %s\nIl manque %s octets !"), isoDir, LLSize2Giga( -fsize ) );
 
809
                return( -1 );
 
810
        }
 
811
/* Verify that we can create a file on isodir */
 
812
        if( CanCreateFile( isoDir ) == 0 ) {
 
813
                PlayError();
 
814
                MessageBoxError( _("Pas le droit de créer de fichier dans %s !"), isoDir );
 
815
                return( -1 );
 
816
        }
 
817
/* Verify number of audio tracks selected */
 
818
        for( i = 0; i < MAX_AUDIO_TRACK; i++ ) {
 
819
                if( audioMap->audioTracks[i] )  nbAudio++;
 
820
        }
 
821
        if( nbAudio != 1 ) {
 
822
                PlayError();
 
823
                MessageBoxError( _("Sélectionnez qu'un seule piste audio !") );
 
824
                return( -1 );
 
825
        }
 
826
 
 
827
/* Reprise du titre du DVD */
 
828
        item = lookup_widget(GTK_WIDGET(forme), "titre" );
 
829
        text = gtk_entry_get_text( GTK_ENTRY(item) );
 
830
        strcpy( TitreDvd, text );
 
831
 
 
832
        FreeCellArray( &CellArray );
 
833
        BuildCells( noPisteVideo, &CellArray, lastCellF );
 
834
 
 
835
        CurVTS = 0;
 
836
        CurVOB = 0;
 
837
        OutSize = 0;
 
838
        TotalSize = 0;
 
839
        CreateAvancement( forme );
 
840
 
 
841
        nbSteps = CountSelectedCells( &CellArray ) + profile->passNb;
 
842
        SetTotalSteps( nbSteps );
 
843
 
 
844
        DisplayAvancement( _("Copie de %d cellules.\n"), CountSelectedCells( &CellArray ) );
 
845
/*      Create empty filesystem tree */
 
846
        DisplayAvancement( _("Effacement des anciens fichiers.\n"));
 
847
 
 
848
        sprintf( injectionFile, "%s/vapinj.%d", tmpDir, getpid());
 
849
        sprintf( targetDir, "%s/%s", tmpDir, TitreDvd );
 
850
        sprintf( aviFile, "%s/%s.%s", isoDir, TitreDvd, profile->extension );
 
851
        sprintf( vobFile, "%s/%s.vob", tmpDir, TitreDvd );
 
852
        sprintf( logFile, "%s/%s.log", tmpDir, TitreDvd );
 
853
 
 
854
        if( FileExist( vobFile ) == 1 ) {
 
855
                res = MessageBoxYesNo( _("Le fichier %s existe. L'utiliser ?"), vobFile );
 
856
                if( res == 1 ) {
 
857
                        vobOk = 1;
 
858
                        goto doAvi;
 
859
                }
 
860
                unlink( vobFile );
 
861
        }
 
862
        OutFpVideo = fopen64( vobFile, "w" );
 
863
        if( !OutFpVideo ) {
 
864
                PlayError();
 
865
                MessageBoxError( _("Création de %s impossible !"), vobFile );
 
866
                DestroyAvancement();
 
867
                return( -1 );
 
868
        }
 
869
 
 
870
/* Setup vaporizer */
 
871
        if( VaporizeInit( Readin, OutputFlux, 1 ) < 0 ) {
 
872
                ret = -1; goto out;
 
873
        }
 
874
/* Setup tracks & factor */
 
875
        for( i = 0; i < MAX_AUDIO_TRACK; i++ ) {
 
876
                if( audioMap->audioTracks[i] ) {
 
877
                        int id = GetAudioId( noPisteVideo, i );
 
878
 
 
879
                        DBG('b',fprintf(stderr,"%s: VaporizeAudio(%d)\n", __FUNCTION__, id ););
 
880
                        VaporizeAudio( id );
 
881
                }
 
882
        }
 
883
        Mpeg2Init();
 
884
/* Must be 100% */
 
885
        VaporizeFactor( 1.0f, 0 );
 
886
        VaporizeInjection( injectionFile );
 
887
 
 
888
/* Copy cells */
 
889
        for( i = 0; i < CellArray.nbCells; i++ ) {
 
890
                Cell_t * c = CellArray.cells + i;
 
891
 
 
892
                if( CopyCell( c, targetDir ) < 0 ) {
 
893
                        ret = -1;
 
894
                        goto out;
 
895
                }
 
896
                if( c->selected ) NewStep();
 
897
        }
 
898
 
 
899
        {
 
900
                int vVideoSize;
 
901
                int vAudioSize;
 
902
                int vSubpSize;
 
903
                int vNavSize;
 
904
 
 
905
                VaporizeSizes( &vVideoSize, &vAudioSize, &vSubpSize, &vNavSize );
 
906
 
 
907
                DBG( 'b',fprintf(stderr,"VAPORIZE VIDEO SIZE: %lld\n", (long long)vVideoSize * DVD_BLOCK_LEN ););
 
908
                DBG( 'b',fprintf(stderr,"VAPORIZE AUDIO SIZE: %lld\n", (long long)vAudioSize * DVD_BLOCK_LEN ););
 
909
                DBG( 'b',fprintf(stderr,"VAPORIZE SUBP  SIZE: %lld\n", (long long)vSubpSize * DVD_BLOCK_LEN ););
 
910
                DBG( 'b',fprintf(stderr,"VAPORIZE NAV   SIZE: %lld\n", (long long)vNavSize * DVD_BLOCK_LEN ););
 
911
        }
 
912
        vobOk = 1;
 
913
out:;
 
914
 
 
915
        VaporizeTerm();
 
916
 
 
917
        if( OutFpVideo ) { fclose( OutFpVideo ); OutFpVideo = NULL; }
 
918
 
 
919
        Mpeg2End();
 
920
 
 
921
doAvi:;
 
922
 
 
923
/* Here calculate bitrate */
 
924
        if( !ret ) {
 
925
                double audioSize;
 
926
                double videoSize;
 
927
                double bitrate;
 
928
                char * cmdLine;
 
929
                char cropParam[1024];
 
930
                int cx,cy,dx,dy;
 
931
                EncodingInfos_t infos;
 
932
 
 
933
                HideMpegVisu();
 
934
 
 
935
                TotalAudioSize( noPisteVideo, &duree );
 
936
                infos.aspect = GetAspectRatio( noPisteVideo );
 
937
 
 
938
                audioSize = ( (double)profile->audioBitrate * (double)duree ) / 8.0;
 
939
                videoSize = profile->fileSize - audioSize;
 
940
                videoSize -= videoSize * profile->overhead; /* Apply container overhead */
 
941
                bitrate = ( videoSize * 8.0 ) / (double)duree;
 
942
                bitrate /= 1000;
 
943
                infos.bitrate = rint(bitrate);
 
944
 
 
945
                DBG( 'b',fprintf(stderr,"Bitrate: %dK\n", infos.bitrate ););
 
946
                *cropParam = 0;
 
947
                CropDetection( vobFile, cropParam );
 
948
                infos.cropParam = cropParam;
 
949
/* Parse croping params */
 
950
                if( sscanf( cropParam, "%d:%d:%d:%d", &cx,&cy,&dx,&dy ) != 4 ) {
 
951
                        cx = 720;
 
952
                        cy = 576;
 
953
                }
 
954
                GetPictureSizes( noPisteVideo, profile, cx, cy, &infos.scaleX, &infos.scaleY, infos.bitrate );
 
955
                infos.vobFile = vobFile;
 
956
                infos.aviFile = aviFile;
 
957
                infos.logFile = logFile;
 
958
                ret = -1;
 
959
 
 
960
                if( !strcmp( profile->encTool, "ffmpeg" ) ) {
 
961
                        cmdLine = ComputeCmdLine( profile, &infos, 1 );
 
962
                        DBG( 'b',fprintf(stderr,"COMMANDLINE: %s\n", cmdLine ););
 
963
                        DisplayAvancement( _("Encodage\n"));
 
964
                        ret = ExecuteFfmpeg( cmdLine, duree );
 
965
//                      if( !ret )      FixAvi( aviFile );
 
966
                        free( cmdLine );
 
967
                }
 
968
                if( !strcmp( profile->encTool, "mencoder" ) ) {
 
969
                        int i;
 
970
 
 
971
                        ret = 0;
 
972
                        for( i = 0; i < profile->passNb; i++ ) {
 
973
                                cmdLine = ComputeCmdLine( profile, &infos, i+1 );
 
974
                                DBG( 'b',fprintf(stderr,"COMMANDLINE: %s\n", cmdLine ););
 
975
                                DisplayAvancement( _("Encodage passe %d\n"), i+1);
 
976
                                res = ExecuteMencoder( cmdLine, duree );
 
977
                                if( res < 0 ) {
 
978
                                        ret = -1;
 
979
                                        if( IsUserStop() && i == 0 && profile->passNb > 1 ) {
 
980
                                                res = MessageBoxYesNo( _("Continuer en passe 2 ?") );
 
981
                                                if( res == 1 ) {
 
982
                                                        ResetUserStop();
 
983
                                                }
 
984
                                        }
 
985
                                }
 
986
                                free( cmdLine );
 
987
                        }
 
988
                }
 
989
                aviDone = 1;
 
990
        }
 
991
        DestroyAvancement();
 
992
        FreeAll();
 
993
        if( !ret )
 
994
                PlaySuccess();
 
995
        else
 
996
                PlayError();
 
997
        if( vobOk ) {
 
998
                res = MessageBoxYesNo( _("Conserver le fichier vob pour un autre encodage ?") );
 
999
                if( res != 1 )  vobOk = 0;
 
1000
        }
 
1001
        if( !vobOk )    unlink( vobFile );
 
1002
 
 
1003
        if( ret == -1 && aviDone ) {
 
1004
                res = MessageBoxYesNo( _("Conserver le fichier %s ?"),  aviFile );
 
1005
                if( res != 1 )  unlink( aviFile );
 
1006
        }
 
1007
        unlink( logFile );
 
1008
        return( ret );
 
1009
}