ffmpeg param visibility, high422 x264 profile, bd/dvd enhancements
authorGood Guy <[email protected]>
Mon, 9 May 2016 22:24:40 +0000 (16:24 -0600)
committerGood Guy <[email protected]>
Mon, 9 May 2016 22:24:40 +0000 (16:24 -0600)
15 files changed:
cinelerra-5.1/cinelerra/bdcreate.C
cinelerra-5.1/cinelerra/bdcreate.h
cinelerra-5.1/cinelerra/bdwrite.C
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/dvdcreate.C
cinelerra-5.1/cinelerra/dvdcreate.h
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/ffmpeg.h
cinelerra-5.1/cinelerra/fileffmpeg.C
cinelerra-5.1/cinelerra/fileffmpeg.h
cinelerra-5.1/cinelerra/fileffmpeg.inc
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/ffmpeg/video/bluray1.m2ts [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/ffmpeg.patch2 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/libbluray.patch1 [new file with mode: 0644]

index 20ecf5878e2da821200d1bc0f902d03cc9eff26b..d487830c9d7dcd781827aa2fcabea14f478c5339 100644 (file)
@@ -30,7 +30,7 @@
 #define BD_1920x1080_2500i     1
 #define BD_1920x1080_2400p     2
 #define BD_1920x1080_23976p    3
-#define BD_1280x720_5997p      4
+#define BD_1280x720_5994p      4
 #define BD_1280x720_5000p      5
 #define BD_1280x720_23976p     6
 #define BD_1280x720_2400p      7
@@ -46,7 +46,7 @@ static struct bd_format {
        { "1920x1080 25i",        1920,1080, 25     },
        { "1920x1080 24p",        1920,1080, 24     },
        { "1920x1080 23.976p",    1920,1080, 23.976 },
-       { "1280x720 59.97p",      1280,720,  59.97  },
+       { "1280x720 59.94p",      1280,720,  59.94  },
        { "1280x720 50p",         1280,720,  50     },
        { "1280x720 23.976p",     1280,720,  23.976 },
        { "1280x720 24p",         1280,720,  24     },
@@ -184,7 +184,8 @@ int CreateBD_Thread::create_bd_jobs(ArrayList<BatchRenderJob*> *jobs,
        fprintf(fp,"bdwrite $1/udfs $1/bd.m2ts\n");
        fprintf(fp,"umount $1/udfs\n");
        fprintf(fp,"echo To burn bluray, load writable media and run:\n");
-       fprintf(fp,"echo growisofs -dvd-compat -Z /dev/bd=$1/bd.udfs\n");
+       fprintf(fp,"echo for WORM: growisofs -dvd-compat -Z /dev/bd=$1/bd.udfs\n");
+       fprintf(fp,"echo for RW:   dd if=$1/bd.udfs of=/dev/bd bs=2048000\n");
        fprintf(fp,"\n");
        fclose(fp);
 
@@ -373,7 +374,7 @@ BC_Window* CreateBD_Thread::new_gui()
                        has_standard = i;  break;
                }
        }
-       use_standard = has_standard >= 0 ? has_standard : BD_1920x1080_2400p;
+       use_standard = has_standard >= 0 ? has_standard : BD_1920x1080_23976p;
 
        option_presets();
        int scr_x = mwindow->gui->get_screen_x(0, -1);
@@ -616,6 +617,7 @@ CreateBD_GUI::CreateBD_GUI(CreateBD_Thread *thread, int x, int y, int w, int h)
        cancel_x = cancel_y = cancel_w = cancel_h = 0;
        asset_title = 0;
        tmp_path = 0;
+       btmp_path = 0;
        disk_space = 0;
        need_deinterlace = 0;
        need_inverse_telecine = 0;
@@ -645,11 +647,15 @@ void CreateBD_GUI::create_objects()
        asset_title = new CreateBD_AssetTitle(this, at_x, at_y, get_w()-at_x-10);
        add_subwindow(asset_title);
        y += title->get_h() + pady/2;
-       title = new BC_Title(x, y, _("tmp path:"), MEDIUMFONT, YELLOW);
+       title = new BC_Title(x, y, _("Work path:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        tmp_x = x + title->get_w();  tmp_y = y;
-       tmp_path = new CreateBD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-10);
+       tmp_path = new CreateBD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-35);
        add_subwindow(tmp_path);
+       btmp_path = new BrowseButton(thread->mwindow, this, tmp_path,
+               tmp_x+tmp_path->get_w(), tmp_y, "/tmp",
+               _("Work path"), _("Select a Work directory:"), 1);
+       add_subwindow(btmp_path);
        y += title->get_h() + pady/2;
        disk_space = new CreateBD_DiskSpace(this, x, y);
        add_subwindow(disk_space);
@@ -711,7 +717,8 @@ void CreateBD_GUI::create_objects()
 int CreateBD_GUI::resize_event(int w, int h)
 {
        asset_title->reposition_window(at_x, at_y, get_w()-at_x-10);
-       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-10);
+       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-35);
+       btmp_path->reposition_window(tmp_x+tmp_path->get_w(), tmp_y);
        ok_y = h - ok_h - 10;
        ok->reposition_window(ok_x, ok_y);
        cancel_x = w - cancel_w - 10,
index 308208dc1366965f98e90c14d707e1b456283f8e..f13bee747f6c4ece8b19394c34b0c3c2a36eeb6a 100644 (file)
@@ -9,6 +9,7 @@
 #include "bclistboxitem.inc"
 #include "bcmenuitem.h"
 #include "bctextbox.h"
+#include "browsebutton.h"
 #include "mwindow.h"
 
 #include "bdcreate.inc"
@@ -209,6 +210,7 @@ public:
        CreateBD_AssetTitle *asset_title;
        int tmp_x, tmp_y;
        CreateBD_TmpPath *tmp_path;
+       BrowseButton *btmp_path;
        CreateBD_DiskSpace *disk_space;
        CreateBD_Format *standard;
        ArrayList<BC_ListBoxItem *> media_sizes;
index 93b656904734ab4080980bc40a90b15b6c03f9a6..a26d56aa796f416fbb037090e6dc10446c96b70d 100644 (file)
@@ -2882,8 +2882,8 @@ bd_path(const char *bp, const char *fmt, va_list ap)
 int Media::
 bd_copy(const char *ifn, const char *fmt, ...)
 {
-  int n, ret = 1;
-  char bfr[0x40000];
+  int bfrsz = 0x40000, ret = 1;
+  char bfr[bfrsz];
   FILE *ifp = fopen(ifn,"r");
   if( ifp ) {
     va_list ap;
@@ -2894,9 +2894,27 @@ bd_copy(const char *ifn, const char *fmt, ...)
     if( ofp ) {
       setvbuf(ifp, 0, _IOFBF, 0x80000);
       setvbuf(ofp, 0, _IOFBF, 0x80000);
-      while( (n=fread(bfr,1,sizeof(bfr),ifp)) > 0 ) fwrite(bfr,1,n,ofp);
-      fclose(ofp);
       ret = 0;
+      int n = bfrsz;
+      while( !ret && n >= bfrsz ) {
+       n = fread(bfr,1,bfrsz,ifp);
+        if( n > 0 && (int)fwrite(bfr,1,n,ofp) != n ) {
+          fprintf(stderr, "cant write: %s\n",filename);
+          ret = 1;
+       }
+      }
+      if( ferror(ifp) ) {
+        fprintf(stderr, "read error: %s = %m\n",ifn);
+        ret = 1;
+      }
+      if( ferror(ofp) ) {
+        fprintf(stderr, "write error: %s = %m\n",filename);
+        ret = 1;
+      }
+      if( fclose(ofp) ) {
+        fprintf(stderr, "close error: %s = %m\n",filename);
+        ret = 1;
+      }
     }
     fclose(ifp);
   }
index 73c11dc5cca985735f44b0239af095aba5f2a2d4..172ee6e3cbbc88c115aa80fdb8887d4b964009da 100644 (file)
@@ -1530,6 +1530,14 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float x2 = point2->x + point2->control_x1;
                                float y2 = point2->y + point2->control_y1;
                                float x3 = point2->x, y3 = point2->y;
+                               float canvas_x0 = (x0 - half_track_w) * projector_z + projector_x;
+                               float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y;
+                               float canvas_x1 = (x1 - half_track_w) * projector_z + projector_x;
+                               float canvas_y1 = (y1 - half_track_h) * projector_z + projector_y;
+                               float canvas_x2 = (x2 - half_track_w) * projector_z + projector_x;
+                               float canvas_y2 = (y2 - half_track_h) * projector_z + projector_y;
+                               float canvas_x3 = (x3 - half_track_w) * projector_z + projector_x;
+                               float canvas_y3 = (y3 - half_track_h) * projector_z + projector_y;
 
                                float t = (float)j / segments;
                                float tpow2 = t * t;
@@ -1546,9 +1554,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        + 3 * t     * invtpow2 * y1
                                        + 3 * tpow2 * invt     * y2
                                        +     tpow3            * y3);
-
-                               x = (x - half_track_w) * projector_z + projector_x;
-                               y = (y - half_track_h) * projector_z + projector_y;
+                               float canvas_x = (x - half_track_w) * projector_z + projector_x;
+                               float canvas_y = (y - half_track_h) * projector_z + projector_y;
 // Test new point addition
                                if(button_press) {
                                        float line_distance = line_dist(x,y, mask_cursor_x,mask_cursor_y);
@@ -1565,13 +1572,9 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
 
 // Test existing point selection
-                                       float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
-                                       float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
 // Test first point
                                        if(gui->ctrl_down()) {
-                                               float control_x = (x1 - half_track_w) * projector_z + projector_x;
-                                               float control_y = (y1 - half_track_h) * projector_z + projector_y;
-                                               float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
+                                               float distance = line_dist(x1,y1, mask_cursor_x,mask_cursor_y);
 
                                                if(distance < selected_control_point_distance) {
                                                        selected_point = i;
@@ -1581,7 +1584,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
                                        else {
                                                if(!gui->shift_down()) {
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                                       if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) {
                                                                selected_point = i;
                                                        }
                                                }
@@ -1590,13 +1593,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                }
                                        }
 // Test second point
-                                       canvas_x = (x3 - half_track_w) * projector_z + projector_x;
-                                       canvas_y = (y3 - half_track_h) * projector_z + projector_y;
-
                                        if(gui->ctrl_down()) {
-                                               float control_x = (x2 - half_track_w) * projector_z + projector_x;
-                                               float control_y = (y2 - half_track_h) * projector_z + projector_y;
-                                               float distance = line_dist(control_x,control_y, mask_cursor_x,mask_cursor_y);
+                                               float distance = line_dist(x2,y2, mask_cursor_x,mask_cursor_y);
 
 //printf("CWindowCanvas::do_mask %d %f %f\n", i, distance, selected_control_point_distance);
                                                if(distance < selected_control_point_distance) {
@@ -1607,7 +1605,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
                                        else if(i < points.size() - 1) {
                                                if(!gui->shift_down()) {
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                                       if(test_bbox(cursor_x, cursor_y, canvas_x3, canvas_y3)) {
                                                                selected_point = (i < points.size() - 1 ? i + 1 : 0);
                                                        }
                                                }
@@ -1617,14 +1615,13 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
                                }
 
-
-                               output_to_canvas(mwindow->edl, 0, x, y);
+                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
 
                                if(j > 0) {
 
                                        if(draw) { // Draw joining line
-                                               x_points.append((int)x);
-                                               y_points.append((int)y);
+                                               x_points.append((int)canvas_x);
+                                               y_points.append((int)canvas_y);
                                        }
 
                                        if(j == segments) {
@@ -1632,24 +1629,24 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                        if(i < points.size() - 1) {
                                                                if(i == gui->affected_point - 1)
                                                                        get_canvas()->draw_disc(
-                                                                               (int)x - CONTROL_W / 2,
-                                                                               (int)y - CONTROL_W / 2,
+                                                                               (int)canvas_x - CONTROL_W / 2,
+                                                                               (int)canvas_y - CONTROL_W / 2,
                                                                                CONTROL_W, CONTROL_H);
                                                                else
                                                                        get_canvas()->draw_circle(
-                                                                               (int)x - CONTROL_W / 2,
-                                                                               (int)y - CONTROL_W / 2,
+                                                                               (int)canvas_x - CONTROL_W / 2,
+                                                                               (int)canvas_y - CONTROL_W / 2,
                                                                                CONTROL_W, CONTROL_H);
 // char string[BCTEXTLEN];
 // sprintf(string, "%d", (i < points.size() - 1 ? i + 1 : 0));
-// canvas->draw_text((int)x + CONTROL_W, (int)y + CONTROL_W, string);
+// canvas->draw_text((int)canvas_x + CONTROL_W, (int)canvas_y + CONTROL_W, string);
                                                        }
 
 // Draw second control point.  Discard x2 and y2 after this.
-                                                       x2 = (x2 - half_track_w) * projector_z + projector_x;
-                                                       y2 = (y2 - half_track_h) * projector_z + projector_y;
                                                        output_to_canvas(mwindow->edl, 0, x2, y2);
-                                                       get_canvas()->draw_line((int)x, (int)y, (int)x2, (int)y2);
+                                                       get_canvas()->draw_line(
+                                                               (int)canvas_x, (int)canvas_y,
+                                                               (int)canvas_x2, (int)canvas_y2);
                                                        get_canvas()->draw_rectangle(
                                                                (int)x2 - CONTROL_W / 2,
                                                                (int)y2 - CONTROL_H / 2,
@@ -1664,29 +1661,29 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                sprintf(mask_label, "%d",
                                                        mwindow->edl->session->cwindow_mask);
                                                get_canvas()->draw_text(
-                                                       (int)x - FIRST_CONTROL_W,
-                                                       (int)y - FIRST_CONTROL_H,
+                                                       (int)canvas_x - FIRST_CONTROL_W,
+                                                       (int)canvas_y - FIRST_CONTROL_H,
                                                        mask_label);
                                                        
                                                get_canvas()->draw_disc(
-                                                       (int)x - FIRST_CONTROL_W / 2,
-                                                       (int)y - FIRST_CONTROL_H / 2,
+                                                       (int)canvas_x - FIRST_CONTROL_W / 2,
+                                                       (int)canvas_y - FIRST_CONTROL_H / 2,
                                                        FIRST_CONTROL_W, FIRST_CONTROL_H);
                                        }
 
-// Draw first control point.  Discard x1 and y1 after this.
+// Draw first control point.
                                        if(draw) {
-                                               x1 = (x1 - half_track_w) * projector_z + projector_x;
-                                               y1 = (y1 - half_track_h) * projector_z + projector_y;
-                                               output_to_canvas(mwindow->edl, 0, x1, y1);
-                                               get_canvas()->draw_line((int)x, (int)y, (int)x1, (int)y1);
+                                               output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
+                                               get_canvas()->draw_line(
+                                                       (int)canvas_x, (int)canvas_y,
+                                                       (int)canvas_x1, (int)canvas_y1);
                                                get_canvas()->draw_rectangle(
-                                                       (int)x1 - CONTROL_W / 2,
-                                                       (int)y1 - CONTROL_H / 2,
+                                                       (int)canvas_x1 - CONTROL_W / 2,
+                                                       (int)canvas_y1 - CONTROL_H / 2,
                                                        CONTROL_W, CONTROL_H);
 
-                                               x_points.append((int)x);
-                                               y_points.append((int)y);
+                                               x_points.append((int)canvas_x);
+                                               y_points.append((int)canvas_y);
                                        }
                                }
 //printf("CWindowCanvas::do_mask 1\n");
@@ -2006,26 +2003,26 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float y1 = point->y + point->control_y1;
                                float x2 = point->x + point->control_x2;
                                float y2 = point->y + point->control_y2;
-                               float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
-                               float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
+                               float canvas_x0 = (x0 - half_track_w) * projector_z + projector_x;
+                               float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y;
 
-                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                               if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                               output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0);
+                               if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) {
                                        over_point = 1;
                                }
 
                                if(!over_point && gui->ctrl_down()) {
-                                       canvas_x = (x1 - half_track_w) * projector_z + projector_x;
-                                       canvas_y = (y1 - half_track_h) * projector_z + projector_y;
-                                       output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                       float canvas_x1 = (x1 - half_track_w) * projector_z + projector_x;
+                                       float canvas_y1 = (y1 - half_track_h) * projector_z + projector_y;
+                                       output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
+                                       if(test_bbox(cursor_x, cursor_y, canvas_x1, canvas_y1)) {
                                                over_point = 1;
                                        }
                                        else {
-                                               canvas_x = (x2 - half_track_w) * projector_z + projector_x;
-                                               canvas_y = (y2 - half_track_h) * projector_z + projector_y;
-                                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                                               if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                               float canvas_x2 = (x2 - half_track_w) * projector_z + projector_x;
+                                               float canvas_y2 = (y2 - half_track_h) * projector_z + projector_y;
+                                               output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2);
+                                               if(test_bbox(cursor_x, cursor_y, canvas_x2, canvas_y2)) {
                                                        over_point = 1;
                                                }
                                        }
index c7477269e3642f26096c0cba11410bf1ff8dc475..66d93793bdd31956c07c04c831f05181cc3da512 100644 (file)
@@ -187,7 +187,8 @@ int CreateDVD_Thread::create_dvd_jobs(ArrayList<BatchRenderJob*> *jobs,
        fprintf(fp,"  </vmgm>\n");
        fprintf(fp,"  <titleset>\n");
        fprintf(fp,"    <titles>\n");
-       fprintf(fp,"    <video format=\"ntsc\" aspect=\"%d:%d\" resolution=\"%dx%d\"/>\n",
+       fprintf(fp,"    <video format=\"%s\" aspect=\"%d:%d\" resolution=\"%dx%d\"/>\n",
+               use_standard == HD_720x576_2500 ? "pal" : "ntsc",
                (int)session->aspect_w, (int)session->aspect_h,
                session->output_w, session->output_h);
        fprintf(fp,"    <audio format=\"ac3\" lang=\"en\"/>\n");
@@ -705,6 +706,7 @@ CreateDVD_GUI::CreateDVD_GUI(CreateDVD_Thread *thread, int x, int y, int w, int
        cancel_x = cancel_y = cancel_w = cancel_h = 0;
        asset_title = 0;
        tmp_path = 0;
+       btmp_path = 0;
        disk_space = 0;
        need_deinterlace = 0;
        need_inverse_telecine = 0;
@@ -734,11 +736,15 @@ void CreateDVD_GUI::create_objects()
        asset_title = new CreateDVD_AssetTitle(this, at_x, at_y, get_w()-at_x-10);
        add_subwindow(asset_title);
        y += title->get_h() + pady/2;
-       title = new BC_Title(x, y, _("tmp path:"), MEDIUMFONT, YELLOW);
+       title = new BC_Title(x, y, _("Work path:"), MEDIUMFONT, YELLOW);
        add_subwindow(title);
        tmp_x = x + title->get_w();  tmp_y = y;
-       tmp_path = new CreateDVD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-10);
+       tmp_path = new CreateDVD_TmpPath(this, tmp_x, tmp_y,  get_w()-tmp_x-35);
        add_subwindow(tmp_path);
+       btmp_path = new BrowseButton(thread->mwindow, this, tmp_path,
+               tmp_x+tmp_path->get_w(), tmp_y, "/tmp",
+               _("Work path"), _("Select a Work directory:"), 1);
+       add_subwindow(btmp_path);
        y += title->get_h() + pady/2;
        disk_space = new CreateDVD_DiskSpace(this, x, y);
        add_subwindow(disk_space);
@@ -802,7 +808,8 @@ void CreateDVD_GUI::create_objects()
 int CreateDVD_GUI::resize_event(int w, int h)
 {
        asset_title->reposition_window(at_x, at_y, get_w()-at_x-10);
-       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-10);
+       tmp_path->reposition_window(tmp_x, tmp_y,  get_w()-tmp_x-35);
+       btmp_path->reposition_window(tmp_x+tmp_path->get_w(), tmp_y);
        ok_y = h - ok_h - 10;
        ok->reposition_window(ok_x, ok_y);
        cancel_x = w - cancel_w - 10,
index b30ff18eeb1b1e215d556ca1a02bf249b3f2dea6..8e267e8251c3a608a9e518e5fd444215cab0244a 100644 (file)
@@ -9,6 +9,7 @@
 #include "bclistboxitem.inc"
 #include "bcmenuitem.h"
 #include "bctextbox.h"
+#include "browsebutton.h"
 #include "mwindow.h"
 
 #include "dvdcreate.inc"
@@ -217,6 +218,7 @@ public:
        CreateDVD_AssetTitle *asset_title;
        int tmp_x, tmp_y;
        CreateDVD_TmpPath *tmp_path;
+       BrowseButton *btmp_path;
        CreateDVD_DiskSpace *disk_space;
        CreateDVD_Format *standard;
        ArrayList<BC_ListBoxItem *> media_sizes;
index 74d1d74522528855c84bcd5bedf766ed99640070..25cfbe70fc6f89dba9877d0d8d4405816dd4f0c7 100644 (file)
@@ -1137,7 +1137,7 @@ void FFMPEG::get_option_path(char *path, const char *type, const char *spec)
                set_option_path(path, "%s/%s", type, spec);
 }
 
-int FFMPEG::get_format(char *format, const char *path, char *spec)
+int FFMPEG::get_format(char *format, const char *path, const char *spec)
 {
        char option_path[BCTEXTLEN], line[BCTEXTLEN], codec[BCTEXTLEN];
        get_option_path(option_path, path, spec);
@@ -1153,6 +1153,22 @@ int FFMPEG::get_format(char *format, const char *path, char *spec)
        return ret;
 }
 
+int FFMPEG::get_codec(char *codec, const char *path, const char *spec)
+{
+       char option_path[BCTEXTLEN], line[BCTEXTLEN], format[BCTEXTLEN];
+       get_option_path(option_path, path, spec);
+       FILE *fp = fopen(option_path,"r");
+       if( !fp ) return 1;
+       int ret = 0;
+       if( !fgets(line, sizeof(line), fp) ) ret = 1;
+       if( !ret ) {
+               line[sizeof(line)-1] = 0;
+               ret = scan_option_line(line, format, codec);
+       }
+       fclose(fp);
+       return ret;
+}
+
 int FFMPEG::get_file_format()
 {
        int ret = 0;
index 674e2703201b92ffa92b9a91264863fe2e9b9d73..d60337fb2280fae079886751a8e423c4ea9380b6 100644 (file)
@@ -263,7 +263,8 @@ public:
 
        static void set_option_path(char *path, const char *fmt, ...);
        static void get_option_path(char *path, const char *type, const char *spec);
-       static int get_format(char *format, const char *path, char *spec);
+       static int get_format(char *format, const char *path, const char *spec);
+       static int get_codec(char *codec, const char *path, const char *spec);
        static int scan_option_line(char *cp,char *tag,char *val);
        static int load_defaults(const char *path, const char *type,
                 char *codec, char *codec_options, int len);
index 660f750edd143038741c7dda5cfdd01678f1a79b..23e391df2b4c417c1a2ca4cf33efaa49c6ff9759 100644 (file)
@@ -16,6 +16,7 @@
 #include "fileffmpeg.h"
 #include "filesystem.h"
 #include "indexfile.h"
+#include "mainerror.h"
 #include "mainprogress.h"
 #include "mutex.h"
 #include "preferences.h"
@@ -162,12 +163,12 @@ void FileFFMPEG::get_info(char *path, char *text, int len)
 int FileFFMPEG::get_video_info(int track, int &pid, double &framerate,
                int &width, int &height, char *title)
 {
-        if( !ff ) return -1;
-        pid = ff->ff_video_pid(track);
-        framerate = ff->ff_frame_rate(track);
-        width = ff->ff_video_width(track);
-        height = ff->ff_video_height(track);
-        if( title ) *title = 0;
+       if( !ff ) return -1;
+       pid = ff->ff_video_pid(track);
+       framerate = ff->ff_frame_rate(track);
+       width = ff->ff_video_width(track);
+       height = ff->ff_video_height(track);
+       if( title ) *title = 0;
        return 0;
 }
 
@@ -193,7 +194,7 @@ int FileFFMPEG::select_audio_stream(Asset *asset, int astream)
 {
        if( !ff || !asset->audio_data ) return 1;
        asset->sample_rate = ff->ff_sample_rate(astream);
-               asset->audio_length = ff->ff_audio_samples(astream);
+       asset->audio_length = ff->ff_audio_samples(astream);
        return 0;
 }
 
@@ -252,7 +253,7 @@ int FileFFMPEG::close_file()
 
 int FileFFMPEG::write_samples(double **buffer, int64_t len)
 {
-        if( !ff || len < 0 ) return -1;
+       if( !ff || len < 0 ) return -1;
        int stream = 0;
        int ret = ff->encode(stream, buffer, len);
        return ret;
@@ -260,7 +261,7 @@ int FileFFMPEG::write_samples(double **buffer, int64_t len)
 
 int FileFFMPEG::write_frames(VFrame ***frames, int len)
 {
-        if( !ff ) return -1;
+       if( !ff ) return -1;
        int ret = 0, layer = 0;
        for(int i = 0; i < 1; i++) {
                for(int j = 0; j < len && !ret; j++) {
@@ -274,18 +275,18 @@ int FileFFMPEG::write_frames(VFrame ***frames, int len)
 
 int FileFFMPEG::read_samples(double *buffer, int64_t len)
 {
-        if( !ff || len < 0 ) return -1;
+       if( !ff || len < 0 ) return -1;
        int ch = file->current_channel;
        int64_t pos = file->current_sample;
        int ret = ff->decode(ch, pos, buffer, len);
        if( ret > 0 ) return 0;
        memset(buffer,0,len*sizeof(*buffer));
-        return -1;
+       return -1;
 }
 
 int FileFFMPEG::read_frame(VFrame *frame)
 {
-        if( !ff ) return -1;
+       if( !ff ) return -1;
        int layer = file->current_layer;
        int64_t pos = asset->video_length >= 0 ? file->current_frame : 0;
        int ret = ff->decode(layer, pos, frame);
@@ -311,7 +312,7 @@ int FileFFMPEG::get_best_colormodel(Asset *asset, int driver)
        switch(driver) {
        case PLAYBACK_X11:      return BC_RGB888;
        case PLAYBACK_X11_GL:   return BC_YUV888;
-        }
+       }
        return BC_YUV420P;
 }
 
@@ -329,12 +330,14 @@ FFMPEGConfigAudio::FFMPEGConfigAudio(BC_WindowBase *parent_window, Asset *asset)
 
        bitrate = 0;
        audio_options = 0;
+       ff_options_dialog = 0;
 }
 
 FFMPEGConfigAudio::~FFMPEGConfigAudio()
 {
+       delete ff_options_dialog;
        lock_window("FFMPEGConfigAudio::~FFMPEGConfigAudio");
-       if(preset_popup) delete preset_popup;
+       delete preset_popup;
        presets.remove_all_objects();
        unlock_window();
 }
@@ -344,20 +347,20 @@ void FFMPEGConfigAudio::create_objects()
        int x = 10, y = 10;
        lock_window("FFMPEGConfigAudio::create_objects");
 
-        FileSystem fs;
+       FileSystem fs;
        char option_path[BCTEXTLEN];
        FFMPEG::set_option_path(option_path, "audio");
-        fs.update(option_path);
-        int total_files = fs.total_files();
-        for(int i = 0; i < total_files; i++) {
-                const char *name = fs.get_entry(i)->get_name();
+       fs.update(option_path);
+       int total_files = fs.total_files();
+       for(int i = 0; i < total_files; i++) {
+               const char *name = fs.get_entry(i)->get_name();
                if( asset->fformat[0] != 0 ) {
                        const char *ext = strrchr(name,'.');
                        if( !ext ) continue;
                        if( strcmp(asset->fformat, ++ext) ) continue;
                }
-                presets.append(new BC_ListBoxItem(name));
-        }
+               presets.append(new BC_ListBoxItem(name));
+       }
 
        if( asset->acodec[0] ) {
                int k = presets.size();
@@ -379,16 +382,24 @@ void FFMPEGConfigAudio::create_objects()
        bitrate->set_increment(1000);
 
        y += bitrate->get_h() + 10;
-       add_subwindow(new BC_Title(x, y, _("Audio Options:")));
+       BC_Title *title = new BC_Title(x, y, _("Audio Options:"));
+       add_subwindow(title);
+
+       ff_options_dialog = new FFOptionsAudioDialog(this);
+       int x1 = x + title->get_w() + 8;
+       add_subwindow(new FFOptionsViewAudio(this, x1, y, _("view")));
+
        y += 25;
        if( !asset->ff_audio_options[0] && asset->acodec[0] ) {
                FFMPEG::set_option_path(option_path, "audio/%s", asset->acodec);
                FFMPEG::load_options(option_path, asset->ff_audio_options,
                         sizeof(asset->ff_audio_options));
        }
-       add_subwindow(audio_options = new FFAudioOptions(this, x, y, get_w()-x-20, 10,
-                sizeof(asset->ff_audio_options)-1, asset->ff_audio_options));
+       audio_options = new FFAudioOptions(this, x, y, get_w()-x-20, 10,
+                sizeof(asset->ff_audio_options)-1, asset->ff_audio_options);
+       audio_options->create_objects();
        add_subwindow(new BC_OKButton(this));
+       
        show_window(1);
        bitrate->handle_event();
        unlock_window();
@@ -400,10 +411,14 @@ int FFMPEGConfigAudio::close_event()
        return 1;
 }
 
+void FFMPEGConfigAudio::update_options()
+{
+       audio_options->update(asset->ff_audio_options);
+}
 
 FFAudioOptions::FFAudioOptions(FFMPEGConfigAudio *audio_popup,
        int x, int y, int w, int rows, int size, char *text)
- : BC_TextBox(x, y, w, rows, size, text)
+ : BC_ScrollTextBox(audio_popup, x, y, w, rows, text, size)
 {
        this->audio_popup = audio_popup;
 }
@@ -447,7 +462,6 @@ int FFMPEGConfigAudioToggle::handle_event()
        return 1;
 }
 
-
 //======
 
 FFMPEGConfigVideo::FFMPEGConfigVideo(BC_WindowBase *parent_window, Asset *asset)
@@ -481,20 +495,20 @@ void FFMPEGConfigVideo::create_objects()
        add_subwindow(new BC_Title(x, y, _("Compression:")));
        y += 25;
 
-        FileSystem fs;
+       FileSystem fs;
        char option_path[BCTEXTLEN];
        FFMPEG::set_option_path(option_path, "video");
-        fs.update(option_path);
-        int total_files = fs.total_files();
-        for(int i = 0; i < total_files; i++) {
-                const char *name = fs.get_entry(i)->get_name();
+       fs.update(option_path);
+       int total_files = fs.total_files();
+       for(int i = 0; i < total_files; i++) {
+               const char *name = fs.get_entry(i)->get_name();
                if( asset->fformat[0] != 0 ) {
                        const char *ext = strrchr(name,'.');
                        if( !ext ) continue;
                        if( strcmp(asset->fformat, ++ext) ) continue;
                }
-                presets.append(new BC_ListBoxItem(name));
-        }
+               presets.append(new BC_ListBoxItem(name));
+       }
 
        if( asset->vcodec[0] ) {
                int k = presets.size();
@@ -524,15 +538,23 @@ void FFMPEGConfigVideo::create_objects()
        quality->set_boundaries((int64_t)0, (int64_t)31);
 
        y += quality->get_h() + 10;
-       add_subwindow(new BC_Title(x, y, _("Video Options:")));
+       BC_Title *title = new BC_Title(x, y, _("Video Options:"));
+       add_subwindow(title);
+
+       ff_options_dialog = new FFOptionsVideoDialog(this);
+       int x1 = x + title->get_w() + 8;
+       add_subwindow(new FFOptionsViewVideo(this, x1, y, _("view")));
+
        y += 25;
        if( !asset->ff_video_options[0] && asset->vcodec[0] ) {
                FFMPEG::set_option_path(option_path, "video/%s", asset->vcodec);
                FFMPEG::load_options(option_path, asset->ff_video_options,
                         sizeof(asset->ff_video_options));
        }
-       add_subwindow(video_options = new FFVideoOptions(this, x, y, get_w()-x-20, 10,
-                sizeof(asset->ff_video_options)-1, asset->ff_video_options));
+
+       video_options = new FFVideoOptions(this, x, y, get_w()-x-20, 10,
+                sizeof(asset->ff_video_options)-1, asset->ff_video_options);
+       video_options->create_objects();
 
        add_subwindow(new BC_OKButton(this));
        show_window(1);
@@ -549,10 +571,14 @@ int FFMPEGConfigVideo::close_event()
        return 1;
 }
 
+void FFMPEGConfigVideo::update_options()
+{
+       video_options->update(asset->ff_video_options);
+}
 
 FFVideoOptions::FFVideoOptions(FFMPEGConfigVideo *video_popup,
        int x, int y, int w, int rows, int size, char *text)
- : BC_TextBox(x, y, w, rows, size, text)
+ : BC_ScrollTextBox(video_popup, x, y, w, rows, text, size)
 {
        this->video_popup = video_popup;
 }
@@ -645,7 +671,7 @@ int FileFFMPEG::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
                index_state->add_audio_stream(aud->channels, aud->length);
        }
 
-        FileSystem fs;
+       FileSystem fs;
        int64_t file_bytes = fs.get_size(ff->fmt_ctx->filename);
        char *index_path = index_file->index_filename;
 
@@ -678,3 +704,790 @@ int FileFFMPEG::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
        return index_state->create_index(index_path, asset);
 }
 
+
+FFOptions_OptPanel::
+FFOptions_OptPanel(FFOptionsWindow *fwin, int x, int y, int w, int h)
+ : BC_ListBox(x, y, w, h, LISTBOX_TEXT), opts(items[0]), vals(items[1])
+{
+       this->fwin = fwin;
+       update();  // init col/wid/columns
+}
+
+FFOptions_OptPanel::
+~FFOptions_OptPanel()
+{
+}
+
+void FFOptions_OptPanel::create_objects()
+{
+       const char *cols[] = { "option", "value", };
+       const int col1_w = 150;
+       int wids[] = { col1_w, get_w()-col1_w };
+       BC_ListBox::update(&items[0], &cols[0], &wids[0], sizeof(items)/sizeof(items[0]));
+}
+
+int FFOptions_OptPanel::update()
+{
+       opts.remove_all();
+       vals.remove_all();
+       FFOptions &options = fwin->options;
+       for( int i=0; i<options.size(); ++i ) {
+               FFOptions_Opt *opt = options[i];
+               opts.append(opt->item_name);
+               vals.append(opt->item_value);
+       }
+       draw_items(1);
+       return 0;
+}
+
+int FFOptions_OptPanel::cursor_leave_event()
+{
+       hide_tooltip();
+       return 0;
+}
+
+
+FFOptions_OptName::FFOptions_OptName(FFOptions_Opt *opt, const char *nm)
+{
+       this->opt = opt;
+       set_text(nm);
+}
+
+FFOptions_OptName::~FFOptions_OptName()
+{
+}
+
+FFOptions_OptValue::FFOptions_OptValue(FFOptions_Opt *opt)
+{
+       this->opt = opt;
+}
+
+
+void FFOptions_OptValue::update()
+{
+       if( !opt ) return;
+       char val[BCTEXTLEN];  val[0] = 0;
+       opt->get(val, sizeof(val));
+       update(val);
+}
+
+void FFOptions_OptValue::update(const char *v)
+{
+       set_text(v);
+}
+
+FFOptions_Opt::FFOptions_Opt(FFOptions *options, const AVOption *opt, const char *nm)
+{
+       this->options = options;
+       this->opt = opt;
+       item_name = new FFOptions_OptName(this, nm);
+       item_value = new FFOptions_OptValue(this);
+}
+
+FFOptions_Opt::~FFOptions_Opt()
+{
+       delete item_name;
+       delete item_value;
+}
+
+char *FFOptions_Opt::get(char *vp, int sz)
+{
+       char *cp = vp, *ep = vp+sz-1;
+       *cp = 0;
+       if( !opt ) return cp;
+
+       void *obj = (void *)options->obj;
+       uint8_t *bp = 0;
+       if( av_opt_get(obj, opt->name, 0, &bp) >= 0 && bp != 0 ) {
+                const char *val = (const char *)bp;
+               if( opt->unit && *val ) {
+                       int id = atoi(val);
+                       const char *uid = unit_name(id);
+                       if( uid ) val = uid;
+               }
+                cp = sz >= 0 ? strncpy(vp,val,sz) : strcpy(vp, val);
+                if( sz > 0 ) vp[sz-1] = 0;
+                av_freep(&bp);
+               return cp;
+        }
+
+       *vp = 0;
+       return cp;
+}
+
+void FFOptions_Opt::set(const char *val)
+{
+       void *obj = (void *)options->obj;
+       if( !obj || !opt ) return;
+       av_opt_set(obj, opt->name, val, 0);
+}
+
+
+FFOptionsKindItem::FFOptionsKindItem(FFOptionsKind *kind, const char *text, int idx)
+ : BC_MenuItem(text)
+{
+       this->kind = kind;
+       this->idx = idx;
+}
+
+FFOptionsKindItem::~FFOptionsKindItem()
+{
+}
+
+int FFOptionsKindItem::handle_event()
+{
+       FFOptionsWindow *fwin = kind->fwin;
+       FFOptions &options = fwin->options;
+       options.initialize(fwin, idx);
+       fwin->draw();
+       return 1;
+}
+
+const char *FFOptionsKind::kinds[] = {
+       N_("codec"),    // FF_KIND_CODEC
+       N_("ffmpeg"),   // FF_KIND_FFMPEG
+};
+
+FFOptionsKind::
+FFOptionsKind(FFOptionsWindow *fwin, int x, int y, int w)
+ : BC_PopupMenu(x, y, w-calculate_w(0), "")
+{
+       this->fwin = fwin;
+}
+
+FFOptionsKind::
+~FFOptionsKind()
+{
+}
+
+void FFOptionsKind::create_objects()
+{
+       for( int i=0; i<(int)(sizeof(kinds)/sizeof(kinds[0])); ++i )
+               add_item(new FFOptionsKindItem(this, _(kinds[i]), i));
+}
+
+int FFOptionsKind::handle_event()
+{
+       return 1;
+}
+
+void FFOptionsKind::set(int k)
+{
+       this->kind = k;
+       set_text(kinds[k]);
+}
+
+FFOptionsText::
+FFOptionsText(FFOptionsWindow *fwin, int x, int y, int w)
+ : BC_TextBox(x, y, w, 1, (char *)"")
+{
+       this->fwin = fwin;
+}
+
+FFOptionsText::
+~FFOptionsText()
+{
+}
+
+int FFOptionsText::handle_event()
+{
+       return 0;
+}
+
+FFOptionsUnits::
+FFOptionsUnits(FFOptionsWindow *fwin, int x, int y, int w)
+ : BC_PopupMenu(x, y, w, "")
+{
+       this->fwin = fwin;
+}
+
+FFOptionsUnits::
+~FFOptionsUnits()
+{
+}
+
+int FFOptionsUnits::handle_event()
+{
+       const char *text = get_text();
+       if( text && fwin->selected ) {
+               fwin->selected->set(text);
+               fwin->selected->item_value->update();
+               av_dict_set(&fwin->dialog->ff_opts,
+                       fwin->selected->item_name->get_text(),
+                       fwin->selected->item_value->get_text(), 0);
+               fwin->draw();
+       }
+       return 1;
+}
+
+FFOptionsApply::
+FFOptionsApply(FFOptionsWindow *fwin, int x, int y)
+ : BC_GenericButton(x, y, _("Apply"))
+{
+       this->fwin = fwin;
+}
+
+FFOptionsApply::
+~FFOptionsApply()
+{
+}
+
+int FFOptionsApply::handle_event()
+{
+       const char *text = fwin->text->get_text();
+       if( text && fwin->selected ) {
+               fwin->selected->set(text);
+               fwin->selected->item_value->update();
+               av_dict_set(&fwin->dialog->ff_opts,
+                       fwin->selected->item_name->get_text(),
+                       fwin->selected->item_value->get_text(), 0);
+               fwin->draw();
+       }
+       return 1;
+}
+
+FFOptions::FFOptions()
+{
+       avctx = 0;
+       obj = 0;
+}
+
+FFOptions::~FFOptions()
+{
+       remove_all_objects();
+       avcodec_free_context(&avctx);
+}
+
+int FFOptions::cmpr(const void *a, const void *b)
+{
+       FFOptions_Opt *ap = *(FFOptions_Opt **)a;
+       FFOptions_Opt *bp = *(FFOptions_Opt **)b;
+       const char *vap = ap->item_name->get_text();
+       const char *vbp = bp->item_name->get_text();
+       return strcmp(vap, vbp);
+}
+
+void FFOptions::initialize(FFOptionsWindow *win, int kind)
+{
+       remove_all_objects();
+       this->win = win;
+       win->selected = 0;
+       obj = 0;
+       if( !avctx )
+               avctx = avcodec_alloc_context3(win->dialog->codec);
+
+       switch( kind ) {
+       case FF_KIND_CODEC:
+               obj = (const void *)avctx->priv_data;
+               break;
+       case FF_KIND_FFMPEG:
+               obj = (const void *)avctx;
+               break;
+       }
+
+       if( obj ) {
+               FFOptions &conf = *this;
+               const AVOption *opt = 0;
+               while( (opt=av_opt_next(obj, opt)) != 0 ) {
+                       if( opt->type == AV_OPT_TYPE_CONST ) continue;
+                       int dupl = 0;
+                       for( int i=0; !dupl && i<size(); ++i ) {
+                               FFOptions_Opt *fopt = conf[i];
+                               const AVOption *op = fopt->opt;
+                               if( op->offset != opt->offset ) continue;
+                               if( op->type != opt->type ) continue;
+                               dupl = 1;
+                               if( strlen(op->name) < strlen(opt->name) )
+                                       fopt->opt = opt;
+                       }
+                       if( dupl ) continue;
+                       FFOptions_Opt *fopt = new FFOptions_Opt(this, opt, opt->name);
+                       append(fopt);
+                       char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val));
+                       fopt->item_value->update(vp);
+               }
+       }
+
+       qsort(&values[0],size(),sizeof(values[0]),cmpr);
+       win->kind->set(kind);
+       win->panel->update();
+       win->panel->set_yposition(0);
+}
+
+int FFOptions::update()
+{
+       int ret = 0;
+       FFOptions &conf = *this;
+
+       for( int i=0; i<size(); ++i ) {
+               FFOptions_Opt *fopt = conf[i];
+               char val[BCTEXTLEN], *vp = fopt->get(val, sizeof(val));
+               if( !vp || !strcmp(val, fopt->item_value->get_text()) ) continue;
+               fopt->item_value->update(val);
+               ++ret;
+       }
+       return ret;
+}
+
+void FFOptions::dump(FILE *fp)
+{
+       if( !obj ) return;
+       const AVOption *opt = 0;
+       FFOptions &conf = *this;
+
+       while( (opt=av_opt_next(obj, opt)) != 0 ) {
+               if( opt->type == AV_OPT_TYPE_CONST ) continue;
+               int k = size();
+               while( --k >= 0 && strcmp(opt->name, conf[k]->opt->name) );
+               if( k < 0 ) continue;
+               FFOptions_Opt *fopt = conf[k];
+               char val[BCTEXTLEN], *vp = fopt->get(val,sizeof(val));
+               fprintf(fp, "  %s:=%s", opt->name, vp);
+               if( opt->unit ) {
+                       char unt[BCTEXTLEN], *up = unt;
+                       fopt->units(up);
+                       fprintf(fp, "%s", unt);
+               }
+               fprintf(fp, "\n");
+       }
+}
+
+
+void FFOptionsWindow::update(FFOptions_Opt *opt)
+{
+       if( selected != opt ) {
+               if( selected ) selected->item_name->set_selected(0);
+               selected = opt;
+               if( selected ) selected->item_name->set_selected(1);
+       }
+       clear_box(0,0, 0,panel->get_y());
+       char str[BCTEXTLEN], *sp;
+       *(sp=str) = 0;
+       if( opt ) opt->types(sp);
+       type->update(str);
+       *(sp=str) = 0;
+       if( opt ) opt->ranges(sp);
+       range->update(str);
+       while( units->total_items() ) units->del_item(0);
+       char unit[BCSTRLEN];  strcpy(unit, "()");
+       if( opt && opt->opt ) {
+               ArrayList<const char *> names;
+               int n = 0;
+               if( opt->opt->unit ) {
+                       n = opt->units(names);
+                       if( n > 0 ) strcpy(unit,opt->opt->unit);
+               }
+               for( int i=0; i<n; ++i )
+                       units->add_item(new BC_MenuItem(names[i], 0));
+       }
+       units->set_text(unit);
+       char val[BCTEXTLEN];  val[0] = 0;
+       if( opt ) opt->get(val, sizeof(val));
+       text->update(val);
+
+       panel->update();
+}
+
+int FFOptions_OptPanel::selection_changed()
+{
+       FFOptions_Opt *opt = 0;
+       BC_ListBoxItem *item = get_selection(0, 0);
+       if( item ) {
+               FFOptions_OptName *opt_name = (FFOptions_OptName *)item;
+               opt = opt_name->opt;
+       }
+       fwin->update(opt);
+       fwin->panel->set_tooltip(!opt ? 0 : opt->tip());
+       fwin->panel->show_tooltip();
+       return 1;
+}
+
+
+int FFOptions_Opt::types(char *rp)
+{
+       const char *cp = "";
+       if( opt ) switch (opt->type) {
+       case AV_OPT_TYPE_FLAGS: cp = "<flags>";  break;
+       case AV_OPT_TYPE_INT: cp = "<int>"; break;
+       case AV_OPT_TYPE_INT64: cp = "<int64>"; break;
+       case AV_OPT_TYPE_DOUBLE: cp = "<double>"; break;
+       case AV_OPT_TYPE_FLOAT: cp = "<float>"; break;
+       case AV_OPT_TYPE_STRING: cp = "<string>"; break;
+       case AV_OPT_TYPE_RATIONAL: cp = "<rational>"; break;
+       case AV_OPT_TYPE_BINARY: cp = "<binary>"; break;
+       case AV_OPT_TYPE_IMAGE_SIZE: cp = "<image_size>"; break;
+       case AV_OPT_TYPE_VIDEO_RATE: cp = "<video_rate>"; break;
+       case AV_OPT_TYPE_PIXEL_FMT: cp = "<pix_fmt>"; break;
+       case AV_OPT_TYPE_SAMPLE_FMT: cp = "<sample_fmt>"; break;
+       case AV_OPT_TYPE_DURATION: cp = "<duration>"; break;
+       case AV_OPT_TYPE_COLOR: cp = "<color>"; break;
+       case AV_OPT_TYPE_CHANNEL_LAYOUT: cp = "<channel_layout>";  break;
+       case AV_OPT_TYPE_BOOL: cp = "<bool>";  break;
+       default: cp = "<undef>";  break;
+       }
+       return sprintf(rp, "%s", cp);
+}
+int FFOptions_Opt::scalar(double d, char *rp)
+{
+       const char *cp = 0;
+            if( d == INT_MAX ) cp = "INT_MAX";
+       else if( d == INT_MIN ) cp = "INT_MIN";
+       else if( d == UINT32_MAX ) cp = "UINT32_MAX";
+       else if( d == (double)INT64_MAX ) cp = "I64_MAX";
+       else if( d == INT64_MIN ) cp = "I64_MIN";
+       else if( d == FLT_MAX ) cp = "FLT_MAX";
+       else if( d == FLT_MIN ) cp = "FLT_MIN";
+       else if( d == -FLT_MAX ) cp = "-FLT_MAX";
+       else if( d == -FLT_MIN ) cp = "-FLT_MIN";
+       else if( d == DBL_MAX ) cp = "DBL_MAX";
+       else if( d == DBL_MIN ) cp = "DBL_MIN";
+       else if( d == -DBL_MAX ) cp = "-DBL_MAX";
+       else if( d == -DBL_MIN ) cp = "-DBL_MIN";
+       else if( d == 0 ) cp = signbit(d) ? "-0" : "0";
+       else if( isnan(d) ) cp = signbit(d) ? "-NAN" : "NAN";
+       else if( isinf(d) ) cp = signbit(d) ? "-INF" : "INF";
+       else return sprintf(rp, "%g", d);
+       return sprintf(rp, "%s", cp);
+}
+
+int FFOptions_Opt::ranges(char *rp)
+{
+       if( !opt ) return 0;
+       void *obj = (void *)options->obj;
+       if( !obj ) return 0;
+
+       switch (opt->type) {
+       case AV_OPT_TYPE_INT:
+       case AV_OPT_TYPE_INT64:
+       case AV_OPT_TYPE_DOUBLE:
+       case AV_OPT_TYPE_FLOAT: break;
+       default: return 0;;
+       }
+       AVOptionRanges *r = 0;
+       char *cp = rp;
+       if( av_opt_query_ranges(&r, obj, opt->name, AV_OPT_SEARCH_FAKE_OBJ) < 0 ) return 0;
+       for( int i=0; i<r->nb_ranges; ++i ) {
+               cp += sprintf(cp, " (");  cp += scalar(r->range[i]->value_min, cp);
+               cp += sprintf(cp, "..");  cp += scalar(r->range[i]->value_max, cp);
+               cp += sprintf(cp, ")");
+       }
+       av_opt_freep_ranges(&r);
+       return cp - rp;
+}
+
+int FFOptions_Opt::units(ArrayList<const char *> &names)
+{
+       if( !opt || !opt->unit ) return 0;
+       const void *obj = options->obj;
+       if( !obj ) return 0;
+
+       ArrayList<const AVOption *> opts;
+       const AVOption *opt = NULL;
+       while( (opt=av_opt_next(obj, opt)) != 0 ) {
+               if( !opt->unit ) continue;
+               if( opt->type != AV_OPT_TYPE_CONST ) continue;
+               if( strcmp(this->opt->unit, opt->unit) ) continue;
+               int i = opts.size();
+               while( --i >= 0 ) {
+                       if( opts[i]->default_val.i64 != opt->default_val.i64 ) continue;
+                       if( strlen(opts[i]->name) < strlen(opt->name) ) opts[i] = opt;
+                       break;
+               }
+               if( i >= 0 ) continue;
+               opts.append(opt);
+       }
+
+       for( int i=0; i<opts.size(); ++i )
+               names.append(opts[i]->name);
+
+       return names.size();
+}
+
+int FFOptions_Opt::units(char *rp)
+{
+       ArrayList<const char *> names;
+       int n = units(names);
+       if( !n ) return 0;
+       char *cp = rp;
+       cp += sprintf(cp, " [%s:", this->opt->unit);
+       for( int i=0; i<n; ++i )
+               cp += sprintf(cp, " %s", names[i]);
+       cp += sprintf(cp, "]:");
+       return cp - rp;
+}
+
+const char *FFOptions_Opt::unit_name(int id)
+{
+       if( !opt || !opt->unit ) return 0;
+       const void *obj = options->obj;
+       if( !obj ) return 0;
+
+       const char *ret = 0;
+       const AVOption *opt = NULL;
+       while( (opt=av_opt_next(obj, opt)) != 0 ) {
+               if( !opt->unit ) continue;
+               if( opt->type != AV_OPT_TYPE_CONST ) continue;
+               if( strcmp(this->opt->unit, opt->unit) ) continue;
+               if( opt->default_val.i64 != id ) continue;
+               if( !ret ) { ret = opt->name;  continue; }
+               if( strlen(ret) < strlen(opt->name) ) ret = opt->name;
+       }
+
+       return ret;
+}
+
+const char *FFOptions_Opt::tip()
+{
+       return !opt ? 0 : opt->help;
+}
+
+
+FFOptionsWindow::FFOptionsWindow(FFOptionsDialog *dialog)
+ : BC_Window(PROGRAM_NAME ": Options", 60, 30, 640, 400)
+{
+       this->dialog = dialog;
+       this->selected = 0;
+}
+
+FFOptionsWindow::~FFOptionsWindow()
+{
+}
+
+void FFOptionsWindow::create_objects()
+{
+       BC_Title *title;
+       int x = 10, y = 10;
+       add_subwindow(title = new BC_Title(x, y, dialog->codec_name));
+       y += title->get_h() + 10;
+       int x0 = x, y0 = y;
+       add_subwindow(title = new BC_Title(x0, y0, _("Type: ")));
+       x0 += title->get_w() + 8;
+       add_subwindow(type = new BC_Title(x0, y0, (char *)""));
+       x0 = x + 150;
+       add_subwindow(title = new BC_Title(x0, y0, _("Range: ")));
+       x0 += title->get_w() + 8;
+       add_subwindow(range = new BC_Title(x0, y0, (char *)""));
+       x0 = x;
+       y += title->get_h() + 10;
+       add_subwindow(units = new FFOptionsUnits(this, x0, y, 120));
+       x0 += units->get_w() + 8;
+       int x1 = get_w() - BC_GenericButton::calculate_w(this, _("Apply")) - 8;
+       add_subwindow(text = new FFOptionsText(this, x0, y, x1-x0 - 8));
+       add_subwindow(apply = new FFOptionsApply(this, x1, y));
+       y += units->get_h() + 10;
+       add_subwindow(kind = new FFOptionsKind(this, x1, y0, apply->get_w()));
+       kind->create_objects();
+       const char *kind_text = _("Kind:");
+       x1 -= BC_Title::calculate_w(this, kind_text) + 8;
+       add_subwindow(kind_title = new BC_Title(x1, y0, kind_text));
+
+       panel_x = x;  panel_y = y;
+       panel_w = get_w()-10 - panel_x;
+       panel_h = get_h()-10 - panel_y - BC_OKButton::calculate_h();
+       panel = new FFOptions_OptPanel(this, panel_x, panel_y, panel_w, panel_h);
+       add_subwindow(panel);
+       add_subwindow(new BC_OKButton(this));
+       add_subwindow(new BC_CancelButton(this));
+       panel->create_objects();
+       options.initialize(this, FF_KIND_CODEC);
+       draw();
+       show_window(1);
+}
+
+void FFOptionsWindow::draw()
+{
+       update(selected);
+}
+
+int FFOptionsWindow::resize_event(int w, int h)
+{
+       int x1 = w - 8 - kind->get_w();
+       int y = kind->get_y();
+       kind->reposition_window(x1, y);
+       x1 -= kind_title->get_w() + 8;
+       kind_title->reposition_window(x1,y);
+       x1 = get_w() - apply->get_w() - 8;
+       int y1 = units->get_y();
+       apply->reposition_window(x1, y1);
+       int x0 = units->get_x() + units->get_w() + 8;
+       int y0 = units->get_y();
+       text->reposition_window(x0,y0, x1-x0-8);
+       panel_w = get_w()-10 - panel_x;
+       panel_h = get_h()-10 - panel_y;
+       panel->reposition_window(panel_x,panel_y, panel_w, panel_h);
+       return 1;
+}
+
+FFOptionsDialog::FFOptionsDialog()
+ : BC_DialogThread()
+{
+       this->options_window = 0;
+       this->codec_name = 0;
+       this->codec = 0;
+       this->ff_options = 0;
+       this->ff_len = 0;
+       this->ff_opts = 0;
+}
+
+FFOptionsDialog::~FFOptionsDialog()
+{
+       close_window();
+       delete [] codec_name;
+}
+
+void FFOptionsDialog::load_options()
+{
+       char line[BCTEXTLEN];
+       char key[BCSTRLEN], val[BCTEXTLEN];
+       char *bp = ff_options, *dp = bp + ff_len-1;
+       int no = 0;
+       while( bp < dp && *bp != 0 ) {
+               ++no;
+               char *cp = line, *ep = cp+sizeof(line)-1;
+               while( *bp && cp<ep && (*cp=*bp++)!='\n' ) ++cp;
+               *cp = 0;
+               if( line[0] == '#' ) {
+                       sprintf(key,"#%d", no);
+                       av_dict_set(&ff_opts, key, line, 0);
+                       continue;
+               }
+               if( line[0] == '\n' ) continue;
+               if( FFMPEG::scan_option_line(line, key, val) ) continue;
+               av_dict_set(&ff_opts, key, val, 0);
+       }
+}
+
+void FFOptionsDialog::store_options()
+{
+       char *cp = ff_options, *ep = cp + ff_len-1;
+       AVDictionaryEntry *elem = 0;
+       while( (elem=av_dict_get(ff_opts, "", elem, AV_DICT_IGNORE_SUFFIX)) != 0 ) {
+               if( elem->key[0] == '#' ) {
+                       cp += snprintf(cp,ep-cp, "%s\n", elem->value);
+                       continue;
+               }
+               cp += snprintf(cp,ep-cp, "%s=%s\n", elem->key, elem->value);
+       }
+       *cp = 0;
+}
+
+void FFOptionsDialog::start(const char *codec_name, AVCodec *codec, char *options, int len)
+{
+       if( options_window ) {
+               options_window->lock_window("FFOptionsDialog::start");
+               options_window->raise_window();
+               options_window->unlock_window();
+               return;
+       }
+
+       this->codec_name = cstrdup(codec_name);
+       this->codec = codec;
+       this->ff_opts = 0;
+       this->ff_options = options;
+       this->ff_len = len;
+       load_options();
+
+       BC_DialogThread::start();
+}
+
+BC_Window* FFOptionsDialog::new_gui()
+{
+       options_window = new FFOptionsWindow(this);
+       options_window->create_objects();
+       return options_window;
+}
+
+void FFOptionsDialog::handle_done_event(int result)
+{
+       if( !result ) {
+               store_options();
+               update_options();
+       }
+       options_window = 0;
+       delete [] codec_name;  codec_name = 0;
+       av_dict_free(&ff_opts);
+}
+
+FFOptionsAudioDialog::FFOptionsAudioDialog(FFMPEGConfigAudio *aud_config)
+{
+       this->aud_config = aud_config;
+}
+
+FFOptionsAudioDialog::~FFOptionsAudioDialog()
+{
+}
+
+void FFOptionsAudioDialog::update_options()
+{
+       aud_config->update_options();
+}
+
+FFOptionsVideoDialog::FFOptionsVideoDialog(FFMPEGConfigVideo *vid_config)
+{
+       this->vid_config = vid_config;
+}
+
+FFOptionsVideoDialog::~FFOptionsVideoDialog()
+{
+}
+
+void FFOptionsVideoDialog::update_options()
+{
+       vid_config->update_options();
+}
+
+
+FFOptionsViewAudio::FFOptionsViewAudio(FFMPEGConfigAudio *aud_config, int x, int y, const char *text)
+ : BC_GenericButton(x, y, text)
+{
+       this->aud_config = aud_config;
+}
+
+FFOptionsViewAudio::~FFOptionsViewAudio()
+{
+}
+
+int FFOptionsViewAudio::handle_event()
+{
+       AVCodec *codec = 0;
+       char audio_codec[BCSTRLEN]; audio_codec[0] = 0;
+       Asset *asset = aud_config->asset;
+       const char *name = asset->acodec;
+       if( !FFMPEG::get_codec(audio_codec, "audio", name) )
+               codec = avcodec_find_encoder_by_name(audio_codec);
+       if( !codec ) {
+               eprintf(_("no codec named: %s: %s"), name, audio_codec);
+               return 1;
+       }
+       aud_config->ff_options_dialog->start(audio_codec, codec,
+                asset->ff_audio_options, sizeof(asset->ff_audio_options));
+       return 1;
+}
+
+FFOptionsViewVideo::FFOptionsViewVideo(FFMPEGConfigVideo *vid_config, int x, int y, const char *text)
+ : BC_GenericButton(x, y, text)
+{
+       this->vid_config = vid_config;
+}
+
+FFOptionsViewVideo::~FFOptionsViewVideo()
+{
+}
+
+int FFOptionsViewVideo::handle_event()
+{
+       AVCodec *codec = 0;
+       char video_codec[BCSTRLEN]; video_codec[0] = 0;
+       Asset *asset = vid_config->asset;
+       const char *name = asset->vcodec;
+       if( !FFMPEG::get_codec(video_codec, "video", name) )
+               codec = avcodec_find_encoder_by_name(video_codec);
+       if( !codec ) {
+               eprintf(_("no codec named: %s: %s"), name, video_codec);
+               return 1;
+       }
+       vid_config->ff_options_dialog->start(video_codec, codec,
+                asset->ff_video_options, sizeof(asset->ff_video_options));
+       return 1;
+}
+
index 907a65637e1094039024646b616d93d712afcded..a9ce7d9cf458bd3d90efeb85a4611aeafa9ea3b0 100644 (file)
@@ -2,8 +2,10 @@
 #define __FILEFFMPEG_H__
 
 #include "asset.inc" 
+#include "bcdialog.h"
 #include "bcwindowbase.inc"
 #include "bitspopup.inc" 
+#include "ffmpeg.h"
 #include "filebase.h"
 #include "fileffmpeg.inc"
 #include "indexfile.inc"
 #include <unistd.h>
 #include <string.h>
 
-class FileFFMPEG;
-class FFMpegConfigNum;
-class FFMpegAudioNum;
-class FFMpegVideoNum;
-class FFOkButton;
-class FFOptions;
-class FFMPEGConfigAudio;
-class FFAudioOptions;
-class FFMPEGConfigAudioPopup;
-class FFMPEGConfigAudioToggle;
-class FFMPEGConfigVideo;
-class FFVideoOptions;
-class FFMPEGConfigVideoPopup;
-class FFMPEGConfigVideoToggle;
 
 class FileFFMPEG : public FileBase
 {
@@ -129,6 +117,7 @@ public:
        ~FFMPEGConfigAudio();
 
        void create_objects();
+       void update_options();
        int close_event();
 
        ArrayList<BC_ListBoxItem*> presets;
@@ -137,9 +126,10 @@ public:
        FFAudioOptions *audio_options;
        BC_WindowBase *parent_window;
        Asset *asset;
+       FFOptionsDialog *ff_options_dialog;
 };
 
-class FFAudioOptions : public BC_TextBox
+class FFAudioOptions : public BC_ScrollTextBox
 {
 public:
        FFAudioOptions(FFMPEGConfigAudio *audio_popup,
@@ -176,6 +166,7 @@ public:
        ~FFMPEGConfigVideo();
 
        void create_objects();
+       void update_options();
        int close_event();
 
        ArrayList<BC_ListBoxItem*> presets;
@@ -185,9 +176,10 @@ public:
        FFMpegVideoQuality *quality;
        FFVideoOptions *video_options;
        Asset *asset;
+       FFOptionsDialog *ff_options_dialog;
 };
 
-class FFVideoOptions : public BC_TextBox
+class FFVideoOptions : public BC_ScrollTextBox
 {
 public:
        FFVideoOptions(FFMPEGConfigVideo *video_popup,
@@ -230,4 +222,215 @@ public:
        void run();
 };
 
+
+class FFOptions_OptName : public BC_ListBoxItem {
+public:
+       FFOptions_Opt *opt;
+
+       FFOptions_OptName(FFOptions_Opt *opt, const char *nm);
+       ~FFOptions_OptName();
+
+};
+
+class FFOptions_OptValue : public BC_ListBoxItem {
+public:
+       FFOptions_Opt *opt;
+
+       void update();
+       void update(const char *v);
+       FFOptions_OptValue(FFOptions_Opt *opt);
+};
+
+class FFOptions_Opt {
+public:
+       FFOptions *options;
+       const AVOption *opt;
+       FFOptions_OptName *item_name;
+       FFOptions_OptValue *item_value;
+
+       char *get(char *vp, int sz=-1);
+       void set(const char *val);
+       int types(char *rp);
+       int scalar(double d, char *rp);
+       int ranges(char *rp);
+       int units(ArrayList<const char *> &opts);
+       const char *unit_name(int id);
+       int units(char *rp);
+       const char *tip();
+
+       FFOptions_Opt(FFOptions *options, const AVOption *opt, const char *nm);
+       ~FFOptions_Opt();
+};
+
+class FFOptions : public ArrayList<FFOptions_Opt *>
+{
+public:
+       FFOptions();
+       ~FFOptions();
+       FFOptionsWindow *win;
+       AVCodecContext *avctx;
+       const void *obj;
+
+       void initialize(FFOptionsWindow *win, int k);
+       static int cmpr(const void *a, const void *b);
+       int update();
+       void dump(FILE *fp);
+};
+
+class FFOptions_OptPanel : public BC_ListBox {
+public:
+       FFOptions_OptPanel(FFOptionsWindow *fwin, int x, int y, int w, int h);
+       ~FFOptions_OptPanel();
+       void create_objects();
+       int cursor_leave_event();
+
+       FFOptionsWindow *fwin;
+       ArrayList<BC_ListBoxItem*> items[2];
+       ArrayList<BC_ListBoxItem*> &opts;
+       ArrayList<BC_ListBoxItem*> &vals;
+
+       int selection_changed();
+       int update();
+};
+
+class FFOptionsKindItem : public BC_MenuItem
+{
+public:
+       FFOptionsKind *kind;
+       int idx;
+       int handle_event();
+       void show_label();
+
+       FFOptionsKindItem(FFOptionsKind *kind, const char *name, int idx);
+       ~FFOptionsKindItem();
+};
+
+class FFOptionsKind : public BC_PopupMenu
+{
+       static const char *kinds[];
+public:
+       FFOptionsWindow *fwin;
+       int kind;
+
+       void create_objects();
+       int handle_event();
+       void set(int k);
+
+       FFOptionsKind(FFOptionsWindow *fwin, int x, int y, int w);
+       ~FFOptionsKind();
+};
+
+class FFOptionsUnits : public BC_PopupMenu {
+public:
+       FFOptionsWindow *fwin;
+
+       FFOptionsUnits(FFOptionsWindow *fwin, int x, int y, int w);
+       ~FFOptionsUnits();
+       int handle_event();
+};
+
+class FFOptionsText : public BC_TextBox {
+public:
+       FFOptionsWindow *fwin;
+
+       FFOptionsText(FFOptionsWindow *fwin, int x, int y, int w);
+       ~FFOptionsText();
+       int handle_event();
+};
+
+class FFOptionsApply : public BC_GenericButton {
+public:
+       FFOptionsWindow *fwin;
+
+       FFOptionsApply(FFOptionsWindow *fwin, int x, int y);
+       ~FFOptionsApply();
+       int handle_event();
+};
+
+class FFOptionsWindow : public BC_Window
+{
+public:
+       FFOptionsWindow(FFOptionsDialog *dialog);
+       ~FFOptionsWindow();
+
+       void create_objects();
+       void update(FFOptions_Opt *oip);
+       void draw();
+       int resize_event(int w, int h);
+
+       FFOptionsDialog *dialog;
+       FFOptions options;
+
+       FFOptions_OptPanel *panel;
+        int panel_x, panel_y, panel_w, panel_h;
+       BC_Title *type, *range, *kind_title;
+        FFOptions_Opt *selected;
+
+       FFOptionsKind *kind;
+       FFOptionsUnits *units;
+       FFOptionsText *text;
+       FFOptionsApply *apply;
+};
+
+class FFOptionsDialog : public BC_DialogThread
+{
+public:
+       FFOptionsDialog();
+       ~FFOptionsDialog();
+       virtual void update_options() = 0;
+
+       void load_options();
+       void store_options();
+       void start(const char *codec_name, AVCodec *codec, char *ff_options, int ff_len);
+       BC_Window* new_gui();
+       void handle_done_event(int result);
+
+       FFOptionsWindow *options_window;
+       const char *codec_name;
+       AVCodec *codec;
+       char *ff_options;
+       int ff_len;
+       AVDictionary *ff_opts;
+};
+
+class FFOptionsAudioDialog : public FFOptionsDialog
+{
+public:
+       FFMPEGConfigAudio *aud_config;
+       void update_options();
+
+       FFOptionsAudioDialog(FFMPEGConfigAudio *aud_config);
+       ~FFOptionsAudioDialog();
+};
+
+class FFOptionsVideoDialog : public FFOptionsDialog
+{
+public:
+       FFMPEGConfigVideo *vid_config;
+       void update_options();
+
+       FFOptionsVideoDialog(FFMPEGConfigVideo *vid_config);
+       ~FFOptionsVideoDialog();
+};
+
+class FFOptionsViewAudio: public BC_GenericButton
+{
+public:
+       FFOptionsViewAudio(FFMPEGConfigAudio *aud_config, int x, int y, const char *text);
+       ~FFOptionsViewAudio();
+
+       int handle_event();
+       FFMPEGConfigAudio *aud_config;
+};
+
+class FFOptionsViewVideo : public BC_GenericButton
+{
+public:
+       FFOptionsViewVideo(FFMPEGConfigVideo *vid_config, int x, int y, const char *text);
+       ~FFOptionsViewVideo();
+
+       int handle_event();
+       FFMPEGConfigVideo *vid_config;
+};
+
 #endif
index 529beeea1e40d9a57c54111d020371bf1eaa7e73..98006e4f0456d88963e8373fdbee25006fc35f97 100644 (file)
 #define FILEFFMPEG_INC
 
 class FileFFMPEG;
+class FFMpegConfigNum;
+class FFMpegAudioNum;
+class FFMpegAudioBitrate;
+class FFMpegVideoNum;
+class FFMpegVideoBitrate;
+class FFMpegVideoQuality;
 class FFMPEGConfigAudio;
+class FFAudioOptions;
 class FFMPEGConfigAudioPopup;
 class FFMPEGConfigAudioToggle;
 class FFMPEGConfigVideo;
+class FFVideoOptions;
 class FFMPEGConfigVideoPopup;
 class FFMPEGConfigVideoToggle;
+class FFMPEGScanProgress;
+
+class FFOptions_OptName;
+class FFOptions_OptValue;
+class FFOptions_Opt;
+class FFOptions;
+class FFOptions_OptPanel;
+class FFOptionsUnits;
+class FFOptionsText;
+class FFOptionsApply;
+class FFOptionsWindow;
+class FFOptionsDialog;
+class FFOptionsKindItem;
+class FFOptionsKind;
+
+#define FF_KIND_CODEC 0
+#define FF_KIND_FFMPEG 1
 
 #endif
index cdf80b206eebfe6790a595886f76791041903f00..44a7d00562bbaaa5a7565bc40d389e1f1de1bcbf 100644 (file)
@@ -2925,6 +2925,9 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
 {
        w = 1;  h = 1;
        if(!width || !height) return 1;
+       if( width == 720 && (height == 480 || height == 576) ) {
+               w = 4;  h = 3;  return 0; // for NTSC and PAL
+       }
        double ar = (double)width / height;
 // square-ish pixels
        if( EQUIV(ar, 1.0000) ) return 0;
diff --git a/cinelerra-5.1/ffmpeg/video/bluray1.m2ts b/cinelerra-5.1/ffmpeg/video/bluray1.m2ts
new file mode 100644 (file)
index 0000000..a388e6f
--- /dev/null
@@ -0,0 +1,8 @@
+mpegts libx264
+id=0x1011
+profile=high422
+pixel_format=yuv422p
+level=3.0
+preset=medium
+bluray-compat=1
+x264opts keyint=25:min-keyint=4:qpmin=3:qpmax=33:qp_step=4:merange=8
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.patch2 b/cinelerra-5.1/thirdparty/src/ffmpeg.patch2
new file mode 100644 (file)
index 0000000..daa9953
--- /dev/null
@@ -0,0 +1,12 @@
+diff -ru ffmpeg-3.0.orig/libavformat/bluray.c ffmpeg-3.0/libavformat/bluray.c
+--- ffmpeg-3.0.orig/libavformat/bluray.c       2015-03-13 11:34:50.000000000 -0600
++++ ffmpeg-3.0/libavformat/bluray.c    2016-05-09 14:07:34.758713307 -0600
+@@ -28,7 +28,7 @@
+ #include "libavutil/opt.h"
+ #define BLURAY_PROTO_PREFIX     "bluray:"
+-#define MIN_PLAYLIST_LENGTH     180     /* 3 min */
++#define MIN_PLAYLIST_LENGTH     0
+ typedef struct {
+     const AVClass *class;
diff --git a/cinelerra-5.1/thirdparty/src/libbluray.patch1 b/cinelerra-5.1/thirdparty/src/libbluray.patch1
new file mode 100644 (file)
index 0000000..24627a1
--- /dev/null
@@ -0,0 +1,11 @@
+--- a/player_wrappers/xine/input_bluray.c      2016-05-09 14:34:35.934918227 -0600
++++ b/player_wrappers/xine/input_bluray.c      2016-05-09 14:27:59.880028563 -0600
+@@ -1423,7 +1423,7 @@
+   /* load title list */
+-  this->num_title_idx = bd_get_titles(this->bdh, TITLES_RELEVANT, 0);
++  this->num_title_idx = bd_get_titles(this->bdh, TITLES_RELEVANT, MIN_TITLE_LENGTH);
+   LOGMSG("%d titles\n", this->num_title_idx);
+   if (this->num_title_idx < 1)