1 /***************************************************************************
2                           \fn ADM_videoFilterBridge
3                           \brief Interface between editor & filter chain
4                            (c) Mean 2009
5 
6 
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 
19 #include "ADM_cpp.h"
20 #include "ADM_default.h"
21 #include "ADM_videoFilterBridge.h"
22 
23 /**
24     \fn ADM_videoFilterBridge
25 
26 */
ADM_videoFilterBridge(IEditor * editor,uint64_t startTime,uint64_t endTime)27 ADM_videoFilterBridge::ADM_videoFilterBridge(IEditor *editor, uint64_t startTime, uint64_t endTime) : ADM_coreVideoFilter(NULL, NULL)
28 {
29     printf("[VideoFilterBridge] Creating bridge from %" PRIu32" s to %" PRIu32" s\n", (uint32_t)(startTime / 1000000LL), (uint32_t)(endTime / 1000000LL));
30     this->startTime = startTime;
31     this->editor = editor;
32 
33     if (endTime == -1LL)
34     {
35         uint64_t total = editor->getVideoDuration();
36         endTime = total - startTime + 1;
37     }
38 
39     this->endTime = endTime;
40     myName = "Bridge";
41     aviInfo fo;
42     editor->getVideoInfo(&fo);
43     bridgeInfo.width = fo.width;
44     bridgeInfo.height = fo.height;
45     bridgeInfo.frameIncrement = editor->getFrameIncrement();
46     editor->getTimeBase(&(bridgeInfo.timeBaseNum), &(bridgeInfo.timeBaseDen));
47     bridgeInfo.totalDuration = endTime - startTime;
48     rewind();
49 }
50 
51 /**
52     \fn     getNextFrameBase
53     \brief
54 */
getNextFrameBase(uint32_t * frameNumber,ADMImage * image)55 bool         ADM_videoFilterBridge::getNextFrameBase(uint32_t *frameNumber, ADMImage *image)
56 {
57 again:
58     bool r = false;
59 
60     if (firstImage == true)
61     {
62         firstImage = false;
63         r = editor->samePicture(image);
64         lastSentImage = 0;
65         *frameNumber = nextFrame = 0;
66     }
67     else
68     {
69         r =   editor->nextPicture(image);
70         nextFrame++;
71         *frameNumber = nextFrame;
72         lastSentImage++;
73     }
74 
75     if (r == false)
76     {
77         return false;
78     }
79 
80     // Translate pts if any
81     int64_t pts = image->Pts;
82 
83     if (pts > endTime)
84     {
85         ADM_warning("[VideoBridge] This frame is too late (%" PRId64" vs %" PRIu64")\n", pts, endTime);
86         return false;
87     }
88 
89     if (pts < startTime)
90     {
91         ADM_warning("[VideoBridge] This frame is too early (%" PRId64" vs %" PRIu64")\n", pts, startTime);
92         goto again;
93     }
94 
95     // Rescale time
96     image->Pts -= startTime;
97     return true;
98 }
99 
100 /**
101     \fn rewind
102     \brief go or return to the original position...
103 */
rewind(void)104 bool ADM_videoFilterBridge::rewind(void)
105 {
106     return goToTime(0);
107 }
108 
109 /**
110     \fn ADM_videoFilterBridge
111 
112 */
~ADM_videoFilterBridge()113 ADM_videoFilterBridge::~ADM_videoFilterBridge()
114 {
115 
116 }
117 /**
118     \fn getNextFrame
119     \brief
120 */
getNextFrame(uint32_t * frameNumber,ADMImage * image)121 bool         ADM_videoFilterBridge::getNextFrame(uint32_t *frameNumber, ADMImage *image)
122 {
123     return getNextFrameAs(ADM_HW_NONE, frameNumber, image);
124 }
125 
126 /**
127     \fn getNextFrameAs
128     \brief
129 */
getNextFrameAs(ADM_HW_IMAGE type,uint32_t * frameNumber,ADMImage * image)130 bool         ADM_videoFilterBridge::getNextFrameAs(ADM_HW_IMAGE type, uint32_t *frameNumber, ADMImage *image)
131 {
132     if (false == getNextFrameBase(frameNumber, image))
133     {
134         ADM_warning("[Bridge] Base did not get an image\n");
135         return false;
136     }
137 
138     // Check if image is
139     if (ADM_HW_ANY == type)
140     {
141         return true;
142     }
143 
144     if (type != image->refType)
145     {
146         return image->hwDownloadFromRef(); // nope, revert to base type
147     }
148 
149     return true;
150 }
151 
152 /**
153     \fn ADM_videoFilterBridge
154 
155 */
getInfo(void)156 FilterInfo  *ADM_videoFilterBridge::getInfo(void)
157 {
158     return &bridgeInfo;
159 }
160 
161 /**
162     \fn goToTime
163 */
goToTime(uint64_t usSeek)164 bool         ADM_videoFilterBridge::goToTime(uint64_t usSeek)
165 {
166     if (!usSeek)
167     {
168         editor->goToTimeVideo(startTime + usSeek);
169     }
170     else
171     {
172         uint64_t seek = usSeek;
173 
174         if (true == editor->getPKFramePTS(&seek))
175         {
176             editor->goToIntraTimeVideo(seek);
177         }
178         else
179         {
180             ADM_warning("Cannot find previous keyframe\n");
181         }
182     }
183 
184     firstImage = true;
185     lastSentImage = 0;
186     return true;
187 }
188 // EOF
189