You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
4.3 KiB

/*
* H.265 video codec.
* Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
*
* Authors: struktur AG, Dirk Farin <farin@struktur.de>
*
* This file is part of libde265.
*
* libde265 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* libde265 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libde265. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libde265/image-io.h"
#include <assert.h>
ImageSource::ImageSource()
{
}
ImageSource_YUV::ImageSource_YUV()
: mFH(NULL)
{
}
ImageSource_YUV::~ImageSource_YUV()
{
if (mFH) {
fclose(mFH);
}
}
bool ImageSource_YUV::set_input_file(const char* filename, int w,int h)
{
assert(mFH==NULL);
mFH = fopen(filename,"rb");
if (mFH==NULL) {
return false;
}
width =w;
height=h;
mReachedEndOfFile = false;
return true;
}
de265_image* ImageSource_YUV::read_next_image()
{
if (mReachedEndOfFile) return NULL;
de265_image* img = new de265_image;
img->alloc_image(width,height,de265_chroma_420, NULL, false,
NULL, /*NULL,*/ 0, NULL, false);
assert(img); // TODO: error handling
// --- load image ---
uint8_t* p;
int stride;
p = img->get_image_plane(0); stride = img->get_image_stride(0);
for (int y=0;y<height;y++) {
if (fread(p+y*stride,1,width,mFH) != width) {
goto check_eof;
}
}
p = img->get_image_plane(1); stride = img->get_image_stride(1);
for (int y=0;y<height/2;y++) {
if (fread(p+y*stride,1,width/2,mFH) != width/2) {
goto check_eof;
}
}
p = img->get_image_plane(2); stride = img->get_image_stride(2);
for (int y=0;y<height/2;y++) {
if (fread(p+y*stride,1,width/2,mFH) != width/2) {
goto check_eof;
}
}
// --- check for EOF ---
check_eof:
if (feof(mFH)) {
mReachedEndOfFile = true;
delete img;
return NULL;
}
else {
return img;
}
}
/*
ImageSource::ImageStatus ImageSource_YUV::get_status()
{
return Available;
}
*/
de265_image* ImageSource_YUV::get_image(bool block)
{
de265_image* img = read_next_image();
return img;
}
void ImageSource_YUV::skip_frames(int n)
{
int imageSize = width*height*3/2;
fseek(mFH,n * imageSize, SEEK_CUR);
}
ImageSink_YUV::~ImageSink_YUV()
{
if (mFH) {
fclose(mFH);
}
}
bool ImageSink_YUV::set_filename(const char* filename)
{
assert(mFH==NULL);
mFH = fopen(filename,"wb");
return true;
}
void ImageSink_YUV::send_image(const de265_image* img)
{
// --- write image ---
const uint8_t* p;
int stride;
int width = img->get_width();
int height= img->get_height();
p = img->get_image_plane(0); stride = img->get_image_stride(0);
for (int y=0;y<height;y++) {
size_t n = fwrite(p+y*stride,1,width,mFH);
(void)n;
}
p = img->get_image_plane(1); stride = img->get_image_stride(1);
for (int y=0;y<height/2;y++) {
size_t n = fwrite(p+y*stride,1,width/2,mFH);
(void)n;
}
p = img->get_image_plane(2); stride = img->get_image_stride(2);
for (int y=0;y<height/2;y++) {
size_t n = fwrite(p+y*stride,1,width/2,mFH);
(void)n;
}
}
PacketSink_File::PacketSink_File()
: mFH(NULL)
{
}
LIBDE265_API PacketSink_File::~PacketSink_File()
{
if (mFH) {
fclose(mFH);
}
}
LIBDE265_API void PacketSink_File::set_filename(const char* filename)
{
assert(mFH==NULL);
mFH = fopen(filename,"wb");
}
LIBDE265_API void PacketSink_File::send_packet(const uint8_t* data, int n)
{
uint8_t startCode[3];
startCode[0] = 0;
startCode[1] = 0;
startCode[2] = 1;
size_t dummy;
dummy = fwrite(startCode,1,3,mFH);
(void)dummy;
dummy = fwrite(data,1,n,mFH);
(void)dummy;
fflush(mFH);
}