added video image format conversation stuff, derived from mmu_man's ffmpeg decoder, with heavy modifications
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6589 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,9 +3,11 @@ SubDir OBOS_TOP src add-ons media plugins avcodec ;
|
|||||||
UsePrivateHeaders media ;
|
UsePrivateHeaders media ;
|
||||||
|
|
||||||
Addon avcodec : media plugins :
|
Addon avcodec : media plugins :
|
||||||
# avcodec.cpp
|
avcodec.cpp
|
||||||
# codectbl.cpp
|
codectbl.cpp
|
||||||
# video_util.cpp
|
gfx_conv_c.cpp
|
||||||
|
# gfx_conv_mmx.cpp
|
||||||
|
gfx_util.cpp
|
||||||
:
|
:
|
||||||
false
|
false
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -200,8 +200,6 @@ avCodec::Seek(uint32 in_towhat,int64 in_requiredFrame, int64 *inout_frame,
|
|||||||
status_t
|
status_t
|
||||||
avCodec::NegotiateOutputFormat(media_format *inout_format)
|
avCodec::NegotiateOutputFormat(media_format *inout_format)
|
||||||
{
|
{
|
||||||
enum PixelFormat ffPixelFmt;
|
|
||||||
|
|
||||||
PRINT(("[%c] avCodec::Format()\n", isAudio?('a'):('v')));
|
PRINT(("[%c] avCodec::Format()\n", isAudio?('a'):('v')));
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -210,12 +208,6 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
PRINT(("[%c] in_format=%s\n", isAudio?('a'):('v'), buffer));
|
PRINT(("[%c] in_format=%s\n", isAudio?('a'):('v'), buffer));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// close any previous instance
|
|
||||||
if (fCodecInitDone) {
|
|
||||||
fCodecInitDone = false;
|
|
||||||
avcodec_close(ffc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAudio) {
|
if (isAudio) {
|
||||||
media_multi_audio_format outputAudioFormat;
|
media_multi_audio_format outputAudioFormat;
|
||||||
outputAudioFormat = media_raw_audio_format::wildcard;
|
outputAudioFormat = media_raw_audio_format::wildcard;
|
||||||
@@ -237,6 +229,13 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
printf("bit_rate %d, sample_rate %d, channels %d, block_align %d, extradata_size %d\n",
|
printf("bit_rate %d, sample_rate %d, channels %d, block_align %d, extradata_size %d\n",
|
||||||
ffc->bit_rate, ffc->sample_rate, ffc->channels, ffc->block_align, ffc->extradata_size);
|
ffc->bit_rate, ffc->sample_rate, ffc->channels, ffc->block_align, ffc->extradata_size);
|
||||||
|
|
||||||
|
// close any previous instance
|
||||||
|
if (fCodecInitDone) {
|
||||||
|
fCodecInitDone = false;
|
||||||
|
avcodec_close(ffc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// open new
|
||||||
if (avcodec_open(ffc, fCodec) >= 0)
|
if (avcodec_open(ffc, fCodec) >= 0)
|
||||||
fCodecInitDone = true;
|
fCodecInitDone = true;
|
||||||
|
|
||||||
@@ -251,8 +250,13 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
fChunkBufferSize = 0;
|
fChunkBufferSize = 0;
|
||||||
fOutputBufferOffset = 0;
|
fOutputBufferOffset = 0;
|
||||||
fOutputBufferSize = 0;
|
fOutputBufferSize = 0;
|
||||||
|
|
||||||
|
inout_format->require_flags = 0;
|
||||||
|
inout_format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
|
||||||
|
|
||||||
} else { // no AUDIO_CODEC
|
return fCodecInitDone ? B_OK : B_ERROR;
|
||||||
|
|
||||||
|
} else { // VIDEO
|
||||||
|
|
||||||
fOutputVideoFormat = fInputFormat.u.encoded_video.output;
|
fOutputVideoFormat = fInputFormat.u.encoded_video.output;
|
||||||
|
|
||||||
@@ -260,6 +264,8 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
ffc->height = fOutputVideoFormat.display.line_count;
|
ffc->height = fOutputVideoFormat.display.line_count;
|
||||||
ffc->frame_rate = (int)(fOutputVideoFormat.field_rate * ffc->frame_rate_base);
|
ffc->frame_rate = (int)(fOutputVideoFormat.field_rate * ffc->frame_rate_base);
|
||||||
|
|
||||||
|
printf("#### requested video format 0x%x\n", inout_format->u.raw_video.display.format);
|
||||||
|
|
||||||
// make MediaPlayer happy (if not in rgb32 screen depth and no overlay,
|
// make MediaPlayer happy (if not in rgb32 screen depth and no overlay,
|
||||||
// it will only ask for YCbCr, which DrawBitmap doesn't handle, so the default
|
// it will only ask for YCbCr, which DrawBitmap doesn't handle, so the default
|
||||||
// colordepth is RGB32)
|
// colordepth is RGB32)
|
||||||
@@ -269,26 +275,33 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
fOutputVideoFormat.display.format = B_RGB32;
|
fOutputVideoFormat.display.format = B_RGB32;
|
||||||
|
|
||||||
// search for a pixel-format the codec handles
|
// search for a pixel-format the codec handles
|
||||||
while (!fCodecInitDone)
|
// XXX We should try this a couple of times until it succeeds, each time
|
||||||
{
|
// XXX using another format pixel-format that is supported by the decoder.
|
||||||
// find the proper ff pixel format and the convertion func
|
// XXX But libavcodec doesn't seem to offer any way to tell the decoder
|
||||||
conv_func = resolve_colorspace(fOutputVideoFormat.display.format, &ffPixelFmt);
|
// XXX which format it should use.
|
||||||
PRINT(("ffc = %08lx, fCodec = %08lx, conv_func = %08lx\n", ffc, fCodec, conv_func));
|
conv_func = 0;
|
||||||
if (!conv_func)
|
for (int i = 0; i < 1; i++) { // iterate over supported codec formats
|
||||||
PRINT(("no conv_func (1) !\n"));
|
// close any previous instance
|
||||||
|
if (fCodecInitDone) {
|
||||||
if (avcodec_open(ffc, fCodec) >= 0)
|
fCodecInitDone = false;
|
||||||
fCodecInitDone = true;
|
avcodec_close(ffc);
|
||||||
else
|
|
||||||
printf("avCodec: error in avcodec_open()\n");
|
|
||||||
|
|
||||||
conv_func = resolve_colorspace(fOutputVideoFormat.display.format, &ffc->pix_fmt);
|
|
||||||
PRINT(("ffc = %08lx, fCodec = %08lx, conv_func = %08lx, ffcolspace= %s\n", ffc, fCodec, conv_func, pixfmt_to_string(ffc->pix_fmt)));
|
|
||||||
if (!conv_func) {
|
|
||||||
PRINT(("no conv_func (2) !\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
PRINT(("PIXFMT: %s -> %s\n", pixfmt_to_string(ffPixelFmt), pixfmt_to_string(ffc->pix_fmt)));
|
// XXX set n-th ffc->pix_fmt here
|
||||||
|
if (avcodec_open(ffc, fCodec) >= 0) {
|
||||||
|
fCodecInitDone = true;
|
||||||
|
conv_func = resolve_colorspace(fOutputVideoFormat.display.format, ffc->pix_fmt);
|
||||||
|
}
|
||||||
|
if (conv_func != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fCodecInitDone) {
|
||||||
|
printf("avcodec_open() failed!\n");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
if (!conv_func) {
|
||||||
|
printf("no conv_func!\n");
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fOutputVideoFormat.display.format == B_YCbCr422)
|
if (fOutputVideoFormat.display.format == B_YCbCr422)
|
||||||
@@ -298,17 +311,19 @@ avCodec::NegotiateOutputFormat(media_format *inout_format)
|
|||||||
|
|
||||||
inout_format->type = B_MEDIA_RAW_VIDEO;
|
inout_format->type = B_MEDIA_RAW_VIDEO;
|
||||||
inout_format->u.raw_video = fOutputVideoFormat;
|
inout_format->u.raw_video = fOutputVideoFormat;
|
||||||
|
|
||||||
|
inout_format->require_flags = 0;
|
||||||
|
inout_format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
string_for_format(*inout_format, buffer, sizeof(buffer));
|
||||||
|
PRINT(("[%c] out_format=%s\n", isAudio?('a'):('v'), buffer));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("#### returned video format 0x%x\n", inout_format->u.raw_video.display.format);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
inout_format->require_flags = 0;
|
|
||||||
inout_format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS;
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
string_for_format(*inout_format, buffer, sizeof(buffer));
|
|
||||||
PRINT(("[%c] out_format=%s\n", isAudio?('a'):('v'), buffer));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
//#define DO_PROFILING
|
//#define DO_PROFILING
|
||||||
|
|
||||||
#include "video_util.h"
|
#include "gfx_util.h"
|
||||||
|
|
||||||
struct codec_table { CodecID id; media_type type; media_format_family family; uint64 fourcc; const char *prettyname;};
|
struct codec_table { CodecID id; media_type type; media_format_family family; uint64 fourcc; const char *prettyname;};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,181 @@
|
|||||||
|
#include <strings.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "gfx_conv_c.h"
|
||||||
|
|
||||||
|
#define OPTIMIZED 1
|
||||||
|
|
||||||
|
void gfx_conv_null_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
printf("[%d, %d, %d] -> [%d, %d, %d]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]);
|
||||||
|
memcpy(out->data[0], in->data[0], height * in->linesize[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !OPTIMIZED
|
||||||
|
// this one is for SVQ1 :^)
|
||||||
|
// july 2002, mmu_man
|
||||||
|
void gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned char *po, *pi, *pi2, *pi3;
|
||||||
|
// printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]);
|
||||||
|
// memcpy(out->data[0], in->data[0], height * in->linesize[0]);
|
||||||
|
po = out->data[0];
|
||||||
|
pi = in->data[0];
|
||||||
|
pi2 = in->data[1];
|
||||||
|
pi3 = in->data[2];
|
||||||
|
for(i=0; i<height; i++) {
|
||||||
|
for(j=0;j<out->linesize[0];j++)
|
||||||
|
// *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24));
|
||||||
|
*(((long *)po)+j) = (long)(*(pi+2*j) + (*(pi2+(j >> 1)) << 8) + (*(pi+2*j+1) << 16) + (*(pi3+j) << 24));
|
||||||
|
po += out->linesize[0];
|
||||||
|
pi += in->linesize[0];
|
||||||
|
if(i%4 == 1)
|
||||||
|
pi2 += in->linesize[1];
|
||||||
|
else if (i%4 == 3)
|
||||||
|
pi3 += in->linesize[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
// bool toggle=false;
|
||||||
|
unsigned long *po, *po_eol;
|
||||||
|
register unsigned long *p;
|
||||||
|
unsigned long *pi;
|
||||||
|
unsigned short *pi2, *pi3;
|
||||||
|
register unsigned long y1, y2;
|
||||||
|
register unsigned short u, v;
|
||||||
|
register unsigned long a, b, c, d;
|
||||||
|
// printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]);
|
||||||
|
// memcpy(out->data[0], in->data[0], height * in->linesize[0]);
|
||||||
|
po = (unsigned long *)out->data[0];
|
||||||
|
pi = (unsigned long *)in->data[0];
|
||||||
|
pi2 = (unsigned short *)in->data[1];
|
||||||
|
pi3 = (unsigned short *)in->data[2];
|
||||||
|
for(i=0; i<height; i++) {
|
||||||
|
for(p=po, po_eol = (unsigned long *)(((char *)po)+out->linesize[0]); p<po_eol;) {
|
||||||
|
// *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24));
|
||||||
|
y1 = *pi++;
|
||||||
|
y2 = *pi++;
|
||||||
|
u = *pi2;
|
||||||
|
v = *pi3;
|
||||||
|
a = (long)(y1 & 0x0FF | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8) | ((v & 0x0FF) << 24));
|
||||||
|
b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF) << 8) | ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF) << 24));
|
||||||
|
c = (long)(y2 & 0x0FF | ((u& 0x0FF00)) | ((y2 & 0x0FF00) << 8) | ((v & 0x0FF00) << 16));
|
||||||
|
d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF00)) | ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16));
|
||||||
|
// if (toggle) {
|
||||||
|
pi2++;
|
||||||
|
// } else {
|
||||||
|
pi3++;
|
||||||
|
// }
|
||||||
|
// toggle = !toggle;
|
||||||
|
|
||||||
|
*(p++) = a;
|
||||||
|
*(p++) = b;
|
||||||
|
*(p++) = c;
|
||||||
|
*(p++) = d;
|
||||||
|
}
|
||||||
|
po = (unsigned long *)((char *)po + out->linesize[0]);
|
||||||
|
pi = (unsigned long *)(in->data[0] + i * in->linesize[0]);
|
||||||
|
pi2 = (unsigned short *)(in->data[1] + ((i+2)/4) * in->linesize[1]);
|
||||||
|
pi3 = (unsigned short *)(in->data[2] + ((i+3)/4) * in->linesize[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // OPTIMIZED
|
||||||
|
|
||||||
|
// this one is for cyuv
|
||||||
|
// may 2003, mmu_man
|
||||||
|
// XXX: FIXME (== yuv410p atm)
|
||||||
|
void gfx_conv_yuv411p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
gfx_conv_yuv410p_ycbcr422_c(in, out, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DOES CRASH
|
||||||
|
void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned char *po, *pi, *pi2, *pi3;
|
||||||
|
// printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]);
|
||||||
|
// memcpy(out->data[0], in->data[0], height * in->linesize[0]);
|
||||||
|
po = out->data[0];
|
||||||
|
pi = in->data[0];
|
||||||
|
pi2 = in->data[1];
|
||||||
|
pi3 = in->data[2];
|
||||||
|
for(i=0; i<height; i++) {
|
||||||
|
for(j=0;j<out->linesize[0];j++)
|
||||||
|
// *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24));
|
||||||
|
*(((long *)po)+j) = (long)(*(pi+2*j) + (*(pi2+j) << 8) + (*(pi+2*j+1) << 16) + (*(pi3+j) << 24));
|
||||||
|
po += out->linesize[0];
|
||||||
|
pi += in->linesize[0];
|
||||||
|
if(i%2)
|
||||||
|
pi2 += in->linesize[1];
|
||||||
|
else
|
||||||
|
pi3 += in->linesize[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned long *po, *po_eol;
|
||||||
|
register unsigned long *p;
|
||||||
|
unsigned long *pi, *pi2, *pi3;
|
||||||
|
register unsigned long y1, y2, u, v;
|
||||||
|
register unsigned long a, b, c, d;
|
||||||
|
// printf("[%ld, %ld, %ld] -> [%ld, %ld, %ld]\n", in->linesize[0], in->linesize[1], in->linesize[2], out->linesize[0], out->linesize[1], out->linesize[2]);
|
||||||
|
// memcpy(out->data[0], in->data[0], height * in->linesize[0]);
|
||||||
|
po = (unsigned long *)out->data[0];
|
||||||
|
pi = (unsigned long *)in->data[0];
|
||||||
|
pi2 = (unsigned long *)in->data[1];
|
||||||
|
pi3 = (unsigned long *)in->data[2];
|
||||||
|
for(i=0; i<height; i++) {
|
||||||
|
for(p=po, po_eol = (unsigned long *)(((char *)po)+out->linesize[0]); p<po_eol;) {
|
||||||
|
// *(((long *)po)+j) = (long)(*(pi+j) + (*(pi2+j) << 8) + (*(pi+j+3) << 16) + (*(pi3+j) << 24));
|
||||||
|
y1 = *pi++;
|
||||||
|
y2 = *pi++;
|
||||||
|
u = *pi2++;
|
||||||
|
v = *pi3++;
|
||||||
|
a = (long)(y1 & 0x0FF | ((u& 0x0FF) << 8) | ((y1 & 0x0FF00) << 8) | ((v & 0x0FF) << 24));
|
||||||
|
b = (long)(((y1 & 0x0FF0000) >> 16) | ((u& 0x0FF00)) | ((y1 & 0x0FF000000) >> 8) | ((v & 0x0FF00) << 16));
|
||||||
|
c = (long)(y2 & 0x0FF | ((u& 0x0FF0000) >> 8) | ((y2 & 0x0FF00) << 8) | ((v & 0x0FF0000) << 8));
|
||||||
|
d = (long)(((y2 & 0x0FF0000) >> 16) | ((u& 0x0FF000000) >> 16) | ((y2 & 0x0FF000000) >> 8) | ((v & 0x0FF000000)));
|
||||||
|
|
||||||
|
|
||||||
|
*(p++) = a;
|
||||||
|
*(p++) = b;
|
||||||
|
*(p++) = c;
|
||||||
|
*(p++) = d;
|
||||||
|
}
|
||||||
|
po = (unsigned long *)((char *)po + out->linesize[0]);
|
||||||
|
pi = (unsigned long *)(in->data[0] + i * in->linesize[0]);
|
||||||
|
pi2 = (unsigned long *)(in->data[1] + ((i+1)/2) * in->linesize[1]);
|
||||||
|
pi3 = (unsigned long *)(in->data[2] + ((i)/2) * in->linesize[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
gfx_conv_null_c(in, out, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
gfx_conv_null_c(in, out, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gfx_conv_yuv420p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height)
|
||||||
|
{
|
||||||
|
gfx_conv_null_c(in, out, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _GFX_CONV_C_H
|
||||||
|
#define _GFX_CONV_C_H
|
||||||
|
|
||||||
|
// BeOS and libavcodec bitmap formats
|
||||||
|
#include <GraphicsDefs.h>
|
||||||
|
#include "libavcodec/avcodec.h"
|
||||||
|
|
||||||
|
void gfx_conv_null_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv411p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv420p_ycbcr422_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv411p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv420p_rgb32_c(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _GFX_CONV_MMX_H
|
||||||
|
#define _GFX_CONV_MMX_H
|
||||||
|
|
||||||
|
// BeOS and libavcodec bitmap formats
|
||||||
|
#include <GraphicsDefs.h>
|
||||||
|
#include "libavcodec/avcodec.h"
|
||||||
|
|
||||||
|
bool IsMmxCpu();
|
||||||
|
|
||||||
|
void gfx_conv_null_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv411p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv420p_ycbcr422_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
void gfx_conv_yuv410p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv411p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
void gfx_conv_yuv420p_rgb32_mmx(AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
#include <strings.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "gfx_util.h"
|
||||||
|
#include "gfx_conv_c.h"
|
||||||
|
#include "gfx_conv_mmx.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ref docs
|
||||||
|
* http://www.joemaller.com/fcp/fxscript_yuv_color.shtml
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define TRACE(a...) printf(a)
|
||||||
|
#else
|
||||||
|
#define TRACE(a...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#define INCLUDE_MMX defined(__INTEL__)
|
||||||
|
#define INCLUDE_MMX 0
|
||||||
|
|
||||||
|
// this function will try to find the best colorspaces for both the ff-codec and
|
||||||
|
// the Media Kit sides.
|
||||||
|
gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFormat)
|
||||||
|
{
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
bool mmx = IsMmxCpu();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (colorSpace)
|
||||||
|
{
|
||||||
|
case B_RGB32:
|
||||||
|
if (pixelFormat == PIX_FMT_YUV410P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv410p_rgb32_mmx\n");
|
||||||
|
return gfx_conv_yuv410p_rgb32_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv410p_rgb32_c\n");
|
||||||
|
return gfx_conv_yuv410p_rgb32_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV411P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_mmx\n");
|
||||||
|
return gfx_conv_yuv411p_rgb32_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_c\n");
|
||||||
|
return gfx_conv_yuv411p_rgb32_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV420P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv420p_rgb32_mmx\n");
|
||||||
|
return gfx_conv_yuv420p_rgb32_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv420p_rgb32_c\n");
|
||||||
|
return gfx_conv_yuv420p_rgb32_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("resolve_colorspace: %s => B_RGB32: NULL\n", pixfmt_to_string(pixelFormat));
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case B_RGB24_BIG:
|
||||||
|
TRACE("resolve_colorspace: %s => B_RGB24_BIG: NULL\n", pixfmt_to_string(pixelFormat));
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case B_RGB24:
|
||||||
|
TRACE("resolve_colorspace: %s => B_RGB24: NULL\n", pixfmt_to_string(pixelFormat));
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case B_YCbCr422:
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV410P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_mmx\n");
|
||||||
|
return gfx_conv_yuv410p_ycbcr422_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv410p_ycbcr422_c\n");
|
||||||
|
return gfx_conv_yuv410p_ycbcr422_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV411P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_mmx\n");
|
||||||
|
return gfx_conv_yuv411p_ycbcr422_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv411p_ycbcr422_c\n");
|
||||||
|
return gfx_conv_yuv411p_ycbcr422_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV420P) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_mmx\n");
|
||||||
|
return gfx_conv_yuv420p_ycbcr422_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_c\n");
|
||||||
|
return gfx_conv_yuv420p_ycbcr422_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelFormat == PIX_FMT_YUV422) {
|
||||||
|
#if INCLUDE_MMX
|
||||||
|
if (mmx) {
|
||||||
|
TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: gfx_conv_null_mmx\n");
|
||||||
|
return gfx_conv_null_mmx;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: gfx_conv_null_c\n");
|
||||||
|
return gfx_conv_null_c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", pixfmt_to_string(pixelFormat));
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
default:
|
||||||
|
TRACE("resolve_colorspace: default: NULL !!!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pixfmt_to_string(int p)
|
||||||
|
{
|
||||||
|
switch(p) {
|
||||||
|
case PIX_FMT_YUV420P:
|
||||||
|
return "PIX_FMT_YUV420P";
|
||||||
|
case PIX_FMT_YUV422:
|
||||||
|
return "PIX_FMT_YUV422";
|
||||||
|
case PIX_FMT_RGB24:
|
||||||
|
return "PIX_FMT_RGB24";
|
||||||
|
case PIX_FMT_BGR24:
|
||||||
|
return "PIX_FMT_BGR24";
|
||||||
|
case PIX_FMT_YUV422P:
|
||||||
|
return "PIX_FMT_YUV422P";
|
||||||
|
case PIX_FMT_YUV444P:
|
||||||
|
return "PIX_FMT_YUV444P";
|
||||||
|
case PIX_FMT_RGBA32:
|
||||||
|
return "PIX_FMT_RGBA32";
|
||||||
|
case PIX_FMT_YUV410P:
|
||||||
|
return "PIX_FMT_YUV410P";
|
||||||
|
case PIX_FMT_YUV411P:
|
||||||
|
return "PIX_FMT_YUV411P";
|
||||||
|
case PIX_FMT_RGB565:
|
||||||
|
return "PIX_FMT_RGB565";
|
||||||
|
case PIX_FMT_RGB555:
|
||||||
|
return "PIX_FMT_RGB555";
|
||||||
|
default:
|
||||||
|
return "(unknown)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BEGIN_TAG "\033[31m"
|
||||||
|
#define END_TAG "\033[0m"
|
||||||
|
|
||||||
|
void dump_ffframe(AVFrame *frame, const char *name)
|
||||||
|
{
|
||||||
|
const char *picttypes[] = {"no pict type", "intra", "predicted", "bidir pre", "s(gmc)-vop"};
|
||||||
|
printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, ]\n"END_TAG,
|
||||||
|
name,
|
||||||
|
frame->pts,
|
||||||
|
frame->coded_picture_number,
|
||||||
|
frame->display_picture_number,
|
||||||
|
// frame->quality,
|
||||||
|
frame->key_frame?"keyframe, ":"",
|
||||||
|
picttypes[frame->pict_type]);
|
||||||
|
// printf(BEGIN_TAG"\t\tlinesize[] = {%ld, %ld, %ld, %ld}\n"END_TAG, frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3]);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
/
|
||||||
|
/ File: ffutils.h
|
||||||
|
/
|
||||||
|
/ Description: utility functions for ffmpeg codec wrappers for BeOs R5.
|
||||||
|
/
|
||||||
|
/ Disclaimer: This decoder is based on undocumented APIs.
|
||||||
|
/ Therefore it is likely, if not certain, to break in future
|
||||||
|
/ versions of BeOS. This piece of software is in no way
|
||||||
|
/ connected to or even supported by Be, Inc.
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2001 François Revol. All Rights Reserved.
|
||||||
|
/
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __FFUTILS_H__
|
||||||
|
#define __FFUTILS_H__
|
||||||
|
|
||||||
|
// BeOS and libavcodec bitmap formats
|
||||||
|
#include <GraphicsDefs.h>
|
||||||
|
#include "libavcodec/avcodec.h"
|
||||||
|
|
||||||
|
// this function will be used by the wrapper to write into
|
||||||
|
// the Media Kit provided buffer from the self-allocated ffmpeg codec buffer
|
||||||
|
// it also will do some colorspace and planar/chunky conversions.
|
||||||
|
// these functions should be optimized with overlay in mind.
|
||||||
|
//typedef void (*gfx_convert_func) (AVPicture *in, AVPicture *out, long line_count, long size);
|
||||||
|
// will become:
|
||||||
|
typedef void (*gfx_convert_func) (AVFrame *in, AVFrame *out, int width, int height);
|
||||||
|
|
||||||
|
// this function will try to find the best colorspaces for both the ff-codec and
|
||||||
|
// the Media Kit sides.
|
||||||
|
gfx_convert_func resolve_colorspace(color_space cs, PixelFormat pixelFormat);
|
||||||
|
|
||||||
|
const char *pixfmt_to_string(int p);
|
||||||
|
|
||||||
|
void dump_ffframe(AVFrame *frame, const char *name);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user