Skip to content

Commit

Permalink
added very rudimentary compositing
Browse files Browse the repository at this point in the history
  • Loading branch information
Olive Team committed Feb 1, 2018
1 parent 12235b2 commit 19941f2
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 52 deletions.
2 changes: 1 addition & 1 deletion include/olive-viewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class Viewer : public Panel {
void setPlayText();
void setPauseText();
private:
bool canvasInit;
Timeline* timeline;
unsigned int controlCount;
UIButton* viewerControls[5];
bool canvasInit;
const char* playText;
const char* pauseText;
};
Expand Down
79 changes: 31 additions & 48 deletions src/olive-compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,41 @@ extern "C" {
}

void Compositor::compose(Sequence* sequence, SDL_Texture* canvas, unsigned long frame) {
// prepare time test - determine how long it takes to grab this frame
Uint32 start = SDL_GetTicks();

// Update SDL canvas with retrieved image
uint8_t* data;
int pitch;
SDL_LockTexture(canvas, NULL, (void**) &data, &pitch);

// blank canvas
unsigned int datalength = sequence->width * sequence->height * 3;
memset(data, 0, datalength);

for (unsigned int i=0;i<sequence->getClipCount();i++) {
Clip* c = sequence->getClip(i);
if (frame >= c->timelineIn && frame < c->timelineOut) {

// TODO proven memory leaks
if (c->stream->avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { // disables audio stream reading for now
// prepare time test - determine how long it takes to grab this frame
Uint32 start = SDL_GetTicks();

// allocate frame
AVFrame* pFrame = av_frame_alloc();

int dstW = sequence->width;
int dstH = sequence->height;
//int dstW = sequence->width;
//int dstH = sequence->height;

// initialize SWS context for software scaling
struct SwsContext* sws_ctx = sws_getContext(
c->stream->avstream->codecpar->width,
c->stream->avstream->codecpar->height,
static_cast<AVPixelFormat>(c->stream->avstream->codecpar->format),
dstW,
dstH,
AV_PIX_FMT_YUV420P,
c->stream->avstream->codecpar->width,
c->stream->avstream->codecpar->height,
AV_PIX_FMT_RGB24,
SWS_BILINEAR,
NULL,
NULL,
NULL
);

size_t yPlaneSz = dstW * dstH;
size_t uvPlaneSz = dstW * dstH / 4;
Uint8* yPlane = (Uint8*)malloc(yPlaneSz);
Uint8* uPlane = (Uint8*)malloc(uvPlaneSz);
Uint8* vPlane = (Uint8*)malloc(uvPlaneSz);
if (!yPlane || !uPlane || !vPlane) {
printf("[ERROR] Could not allocate pixel buffers.");
}

int uvPitch = dstW / 2;
);

// get values for seek
double timecodeSecs = ((frame - c->timelineIn + c->clipIn) / sequence->frameRate);
Expand Down Expand Up @@ -96,39 +92,26 @@ void Compositor::compose(Sequence* sequence, SDL_Texture* canvas, unsigned long
// assuming we got the targetFrame, record it
c->stream->lastFrame = targetFrame;

// Show pFrame
uint8_t* data[AV_NUM_DATA_POINTERS];
data[0] = yPlane;
data[1] = uPlane;
data[2] = vPlane;
int linesize[AV_NUM_DATA_POINTERS];
linesize[0] = dstW;
linesize[1] = linesize[2] = uvPitch;

// Convert the image into YUV format that SDL uses
sws_scale(sws_ctx, (uint8_t const * const *) pFrame->data, pFrame->linesize, 0, c->stream->avstream->codecpar->height, data, linesize);

if (SDL_UpdateYUVTexture(canvas, NULL, yPlane, dstW, uPlane, uvPitch, vPlane, uvPitch) < 0) {
printf("[ERROR] Could not update texture. %s\n", SDL_GetError());
}

sws_scale(sws_ctx, (uint8_t const * const *) pFrame->data, pFrame->linesize, 0, c->stream->avstream->codecpar->height, &data, &pitch);

av_frame_unref(pFrame);
sws_freeContext(sws_ctx);

free(yPlane);
free(uPlane);
free(vPlane);

double exp = (1000 / sequence->frameRate);
double ret = SDL_GetTicks() - start;
if (ret > exp) {
printf("[WARNING] Frame %lu took too long to render (expected %f, took %f)\n", frame, exp, ret);
}
sws_freeContext(sws_ctx);
} else {
printf("[WARNING] Skipped audio stream because Olive has no audio support yet.\n");
}
}
}

// apply changes to canvas texture
SDL_UnlockTexture(canvas);

// evaluate time taken to render frame
double exp = (1000 / sequence->frameRate);
double ret = SDL_GetTicks() - start;
if (ret > exp) {
printf("[WARNING] Frame %lu took too long to render (expected %f, took %f)\n", frame, exp, ret);
}
}

void Compositor::retrieveNextFrame(Clip* c, AVFrame* f) {
Expand Down
5 changes: 3 additions & 2 deletions src/olive-timeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Timeline::Timeline(Core* c) : Panel(c) {
timelineToolbar[0]->selected = true;

// TODO debug
sequence.frameRate = 23.976;
sequence.frameRate = 29.97;
sequence.width = 1920;
sequence.height = 1080;
}
Expand All @@ -92,7 +92,8 @@ void Timeline::setDependencies(Sources* s, Viewer* v) {
sources = s;
viewer = v;

setPlayhead(0);
//setPlayhead(0);
playhead = 0;
}

void Timeline::render(SDL_Renderer* renderer) {
Expand Down
2 changes: 1 addition & 1 deletion src/olive-viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void Viewer::render(SDL_Renderer* renderer) {
SDL_RenderFillRect(renderer, &canvasRect);*/

if (!canvasInit) {
canvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, timeline->sequence.width, timeline->sequence.height);
canvas = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, timeline->sequence.width, timeline->sequence.height);
if (canvas == NULL) {
printf("[ERROR] Couldn't create viewer texture. %s\n", SDL_GetError());
} else {
Expand Down

0 comments on commit 19941f2

Please sign in to comment.