2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FMedia_BmpEncoder.c
20 * @brief This file contains the implementation of _BmpEncoder class.
24 #include <unique_ptr.h>
25 #include <FMediaImageTypes.h>
26 #include <FBaseSysLog.h>
27 #include "FMedia_Ffmpeg.h"
28 #include "FMedia_BmpEncoder.h"
29 #include "FMedia_ImageUtil.h"
32 using namespace Tizen::Base;
34 namespace Tizen { namespace Media
38 _BmpEncoder::_BmpEncoder(void)
42 __pixelFormat = MEDIA_PIXEL_FORMAT_NONE;
48 _BmpEncoder::~_BmpEncoder(void)
52 avcodec_flush_buffers(__pCodecCtx);
53 avcodec_close(__pCodecCtx);
61 _BmpEncoder::Construct(int width, int height,
62 MediaPixelFormat srcPixelFormat,
63 MediaPixelFormat& reqPixelFormat,
68 SysTryReturnResult(NID_MEDIA, width >= MIN_WIDTH, E_INVALID_ARG,
69 "Width (%d) < minimum bmp width (%d)", width, MIN_WIDTH);
70 SysTryReturnResult(NID_MEDIA, height >= MIN_HEIGHT, E_INVALID_ARG,
71 "Height (%d) < minimum bmp height (%d)", height, MIN_HEIGHT);
72 SysTryReturnResult(NID_MEDIA, quality > 0, E_INVALID_ARG,
73 "Quality should be greater than 0 (%d)", quality);
74 SysTryReturnResult(NID_MEDIA, quality <= 100, E_INVALID_ARG,
75 "Quality should be lesser than 100 (%d)", quality);
77 // TODO: add BGRA8888 support
81 __pixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
82 reqPixelFormat = MEDIA_PIXEL_FORMAT_BGR888;
85 avcodec_register_all();
87 __pCodec = avcodec_find_encoder(CODEC_ID_BMP);
88 SysTryReturnResult(NID_MEDIA, __pCodec != null, E_UNSUPPORTED_CODEC, "Failed to find bmp encoder.");
90 __pCodecCtx = avcodec_alloc_context3(__pCodec);
91 SysTryReturnResult(NID_MEDIA, __pCodecCtx != null, E_OUT_OF_MEMORY, "context allocation failed.");
93 // Context required for opening BMP encoder.
94 // Specifying output image format
95 __pCodecCtx->pix_fmt = (PixelFormat)_ImageUtil::ToFfmpegPixelFormat(__pixelFormat);
96 // Dimensions of the image
97 __pCodecCtx->height = height;
98 __pCodecCtx->width = width;
100 res = avcodec_open2(__pCodecCtx, __pCodec, null);
101 SysTryReturnResult(NID_MEDIA, res >= 0, E_OUT_OF_MEMORY, "codec open failed:%d", res);
106 Tizen::Base::ByteBuffer*
107 _BmpEncoder::EncodeN(const byte* pSrcBuf, int srcLength)
109 result r = E_SUCCESS;
111 unique_ptr<AVFrame, _FfmpegDeleter> pVideoFrame(avcodec_alloc_frame(), ffmpegDeleter);
112 unique_ptr<ByteBuffer> pRetBuf(new (std::nothrow) ByteBuffer());
113 unique_ptr<AVPacket, _FfmpegDeleter> pPkt(new (std::nothrow) AVPacket, ffmpegDeleter);
116 // TODO: apply pixel format
117 SysTryReturn(NID_MEDIA, pSrcBuf != null && srcLength > 0, null, E_INVALID_ARG,
118 "[E_INVALID_ARG] pSrcBuf=0x%x srcLength=%d", pSrcBuf, srcLength);
120 SysTryReturn(NID_MEDIA, pVideoFrame.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] avcodec_alloc_frame() failed");
121 SysTryReturn(NID_MEDIA, pRetBuf.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] new ByteBuffer() failed.");
122 SysTryReturn(NID_MEDIA, pPkt.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] new AVPacket failed.");
124 // Input buffer is a BGR888, so no need for explicit color conversion
127 // pVideoFrame is the input to encoder.
128 pVideoFrame->data[0] = (uint8_t*)pSrcBuf;
129 pVideoFrame->data[1] = 0;
130 pVideoFrame->data[2] = 0;
131 pVideoFrame->data[3] = 0;
132 pVideoFrame->linesize[0] = (__width) * BYTES_PER_PIXEL_RGB;
133 pVideoFrame->linesize[1] = 0;
134 pVideoFrame->linesize[2] = 0;
135 pVideoFrame->linesize[3] = 0;
137 av_init_packet(pPkt.get());
138 pPkt->data = NULL; // packet data will be allocated by the encoder
142 ret = avcodec_encode_video2(__pCodecCtx, pPkt.get(), pVideoFrame.get(), &gotOutput);
143 SysTryReturn(NID_MEDIA, ret >= 0 && gotOutput > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] Encode Failed:%d %d", ret, gotOutput);
145 r = pRetBuf->Construct(pPkt->size);
146 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer.Construct(%d) failed", GetErrorMessage(r), pPkt->size);
148 r = pRetBuf->SetArray(pPkt->data, 0, pPkt->size);
149 SysTryReturn(NID_MEDIA, r == E_SUCCESS, null, r, "[%s] Propagated. ByteBuffer.SetArray(%x, 0, %d) failed",
150 GetErrorMessage(r), pPkt->data, pPkt->size);
153 return pRetBuf.release();
157 _BmpEncoder::SetValue(const Tizen::Base::String& key, Tizen::Base::Object &value)
159 return E_UNSUPPORTED_OPERATION;