generic-pc/video: improve video decoder

* add aspect ratio reporting
* "correct" buffer PTS by 300ms for better AV-Sync with MPEG2
* remove unneeded stuff


Origin commit data
------------------
Branch: master
Commit: 8a8849f28e
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2013-05-04 (Sat, 04 May 2013)



------------------
This commit was generated by Migit
This commit is contained in:
Stefan Seyfried
2013-05-04 17:21:03 +02:00
parent 57db8efaf2
commit 6dadad1412
2 changed files with 50 additions and 13 deletions

View File

@@ -63,7 +63,7 @@ cVideo::cVideo(int, void *, void *)
buf_num = 0; buf_num = 0;
buf_in = 0; buf_in = 0;
buf_out = 0; buf_out = 0;
firstpts = AV_NOPTS_VALUE; v_format = VIDEO_FORMAT_MPEG2;
} }
cVideo::~cVideo(void) cVideo::~cVideo(void)
@@ -80,7 +80,31 @@ int cVideo::setAspectRatio(int, int)
int cVideo::getAspectRatio(void) int cVideo::getAspectRatio(void)
{ {
return 1; buf_m.lock();
int ret = 0;
int w, h, ar;
AVRational a;
if (buf_num == 0)
goto out;
a = buffers[buf_out].AR();
w = buffers[buf_out].width();
h = buffers[buf_out].height();
if (a.den == 0 || h == 0)
goto out;
ar = w * 100 * a.num / h / a.den;
if (ar < 100 || ar > 225) /* < 4:3, > 20:9 */
; /* ret = 0: N/A */
else if (ar < 140) /* 4:3 */
ret = 1;
else if (ar < 165) /* 14:9 */
ret = 2;
else if (ar < 200) /* 16:9 */
ret = 3;
else
ret = 4; /* 20:9 */
out:
buf_m.unlock();
return ret;
} }
int cVideo::setCroppingMode(int) int cVideo::setCroppingMode(int)
@@ -159,19 +183,24 @@ void cVideo::SetSyncMode(AVSYNC_TYPE)
{ {
}; };
int cVideo::SetStreamType(VIDEO_FORMAT) int cVideo::SetStreamType(VIDEO_FORMAT v)
{ {
v_format = v;
return 0; return 0;
} }
cVideo::SWFramebuffer *cVideo::getDecBuf(void) cVideo::SWFramebuffer *cVideo::getDecBuf(void)
{ {
if (buf_num == 0) buf_m.lock();
if (buf_num == 0) {
buf_m.unlock();
return NULL; return NULL;
}
SWFramebuffer *p = &buffers[buf_out]; SWFramebuffer *p = &buffers[buf_out];
buf_out++; buf_out++;
buf_num--; buf_num--;
buf_out %= VDEC_MAXBUFS; buf_out %= VDEC_MAXBUFS;
buf_m.unlock();
return p; return p;
} }
@@ -217,9 +246,8 @@ void cVideo::run(void)
buf_num = 0; buf_num = 0;
buf_in = 0; buf_in = 0;
buf_out = 0; buf_out = 0;
dec_r = 0;
firstpts = AV_NOPTS_VALUE;
framecount = 0;
av_init_packet(&avpkt); av_init_packet(&avpkt);
inp = av_find_input_format("mpegts"); inp = av_find_input_format("mpegts");
AVIOContext *pIOCtx = avio_alloc_context(inbuf, INBUF_SIZE, // internal Buffer and its size AVIOContext *pIOCtx = avio_alloc_context(inbuf, INBUF_SIZE, // internal Buffer and its size
@@ -297,6 +325,7 @@ void cVideo::run(void)
if (!convert) if (!convert)
lt_info("%s: ERROR setting up SWS context\n", __func__); lt_info("%s: ERROR setting up SWS context\n", __func__);
else { else {
buf_m.lock();
SWFramebuffer *f = &buffers[buf_in]; SWFramebuffer *f = &buffers[buf_in];
if (f->size() < need) if (f->size() < need)
f->resize(need); f->resize(need);
@@ -315,7 +344,12 @@ void cVideo::run(void)
} }
f->width(c->width); f->width(c->width);
f->height(c->height); f->height(c->height);
f->pts(av_frame_get_best_effort_timestamp(frame)); int64_t vpts = av_frame_get_best_effort_timestamp(frame);
if (v_format == VIDEO_FORMAT_MPEG2)
vpts += 90000*3/10; /* 300ms */
f->pts(vpts);
AVRational a = av_guess_sample_aspect_ratio(avfc, avfc->streams[0], frame);
f->AR(a);
buf_in++; buf_in++;
buf_in %= VDEC_MAXBUFS; buf_in %= VDEC_MAXBUFS;
buf_num++; buf_num++;
@@ -325,11 +359,9 @@ void cVideo::run(void)
buf_out %= VDEC_MAXBUFS; buf_out %= VDEC_MAXBUFS;
buf_num--; buf_num--;
} }
if (firstpts == AV_NOPTS_VALUE && f->pts() != AV_NOPTS_VALUE)
firstpts = f->pts();
}
dec_r = c->time_base.den/(c->time_base.num * c->ticks_per_frame); dec_r = c->time_base.den/(c->time_base.num * c->ticks_per_frame);
framecount++; buf_m.unlock();
}
lt_debug("%s: time_base: %d/%d, ticks: %d rate: %d pts 0x%" PRIx64 "\n", __func__, lt_debug("%s: time_base: %d/%d, ticks: %d rate: %d pts 0x%" PRIx64 "\n", __func__,
c->time_base.num, c->time_base.den, c->ticks_per_frame, dec_r, c->time_base.num, c->time_base.den, c->ticks_per_frame, dec_r,
av_frame_get_best_effort_timestamp(frame)); av_frame_get_best_effort_timestamp(frame));

View File

@@ -2,9 +2,11 @@
#define _VIDEO_TD_H #define _VIDEO_TD_H
#include <OpenThreads/Thread> #include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
#include <vector> #include <vector>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include "../common/cs_types.h" #include "../common/cs_types.h"
#include <libavutil/rational.h>
typedef enum { typedef enum {
ANALOG_SD_RGB_CINCH = 0x00, ANALOG_SD_RGB_CINCH = 0x00,
@@ -126,16 +128,17 @@ class cVideo : public OpenThreads::Thread
void width(int w) { mWidth = w; } void width(int w) { mWidth = w; }
void height(int h) { mHeight = h; } void height(int h) { mHeight = h; }
void pts(uint64_t p) { mPts = p; } void pts(uint64_t p) { mPts = p; }
void AR(AVRational a) { mAR = a; }
int width() const { return mWidth; } int width() const { return mWidth; }
int height() const { return mHeight; } int height() const { return mHeight; }
int64_t pts() const { return mPts; } int64_t pts() const { return mPts; }
AVRational AR() const { return mAR; }
private: private:
int mWidth; int mWidth;
int mHeight; int mHeight;
int64_t mPts; int64_t mPts;
AVRational mAR;
}; };
int64_t firstpts;
uint64_t framecount;
int buf_in, buf_out, buf_num; int buf_in, buf_out, buf_num;
/* constructor & destructor */ /* constructor & destructor */
cVideo(int mode, void *, void *); cVideo(int mode, void *, void *);
@@ -193,6 +196,8 @@ class cVideo : public OpenThreads::Thread
int dec_r; int dec_r;
bool w_h_changed; bool w_h_changed;
bool thread_running; bool thread_running;
VIDEO_FORMAT v_format;
OpenThreads::Mutex buf_m;
}; };
#endif #endif