1bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/*
2bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee INTEL CONFIDENTIAL
3bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee Copyright 2009 Intel Corporation All Rights Reserved.
4bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
6bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
8bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include <glib.h>
9bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "mixvideolog.h"
10bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
11bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include "mixvideoformat_vc1.h"
12bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include <va/va_x11.h>
13bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
14bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#ifdef YUVDUMP
15bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//TODO Complete YUVDUMP code and move into base class
16bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include <stdio.h>
17bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif /* YUVDUMP */
18bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
19bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#include <string.h>
20bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
21bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
22bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#ifdef MIX_LOG_ENABLE
23bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic int mix_video_vc1_counter = 0;
24bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
25bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
26bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/* The parent class. The pointer will be saved
27bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * in this class's initialization. The pointer
28bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * can be used for chaining method call if needed.
29bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
30bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic MixVideoFormatClass *parent_class = NULL;
31bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
32bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_videoformat_vc1_finalize(GObject * obj);
33bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
34bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/*
35bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee * Please note that the type we pass to G_DEFINE_TYPE is MIX_TYPE_VIDEOFORMAT
36bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee */
37bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeG_DEFINE_TYPE (MixVideoFormat_VC1, mix_videoformat_vc1, MIX_TYPE_VIDEOFORMAT);
38bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
39bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_videoformat_vc1_init(MixVideoFormat_VC1 * self) {
40bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat *parent = MIX_VIDEOFORMAT(self);
41bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
42bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* public member initialization */
43bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* These are all public because MixVideoFormat objects are completely internal to MixVideo,
44bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		no need for private members  */
45bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reference_frames[0] = NULL;
46bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->reference_frames[1] = NULL;
47bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
48bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* NOTE: we don't need to do this here.
49bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 * This just demostrates how to access
50bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 * member varibles beloned to parent
51bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
52bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->initialized = FALSE;
53bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
54bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
55bd8388b4555645b3d29abc6a94c303638064d69awonjong.leestatic void mix_videoformat_vc1_class_init(
56bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixVideoFormat_VC1Class * klass) {
57bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
58bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* root class */
59bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	GObjectClass *gobject_class = (GObjectClass *) klass;
60bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
61bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* direct parent class */
62bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormatClass *video_format_class =
63bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			MIX_VIDEOFORMAT_CLASS(klass);
64bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
65bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* parent class for later use */
66bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent_class = g_type_class_peek_parent(klass);
67bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
68bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* setup finializer */
69bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gobject_class->finalize = mix_videoformat_vc1_finalize;
70bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
71bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* setup vmethods with base implementation */
72bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* This is where we can override base class methods if needed */
73bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->getcaps = mix_videofmt_vc1_getcaps;
74bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->initialize = mix_videofmt_vc1_initialize;
75bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->decode = mix_videofmt_vc1_decode;
76bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->flush = mix_videofmt_vc1_flush;
77bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->eos = mix_videofmt_vc1_eos;
78bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	video_format_class->deinitialize = mix_videofmt_vc1_deinitialize;
79bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
80bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
81bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixVideoFormat_VC1 *
82bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_videoformat_vc1_new(void) {
83bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *ret =
84bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			g_object_new(MIX_TYPE_VIDEOFORMAT_VC1, NULL);
85bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
86bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
87bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
88bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
89bd8388b4555645b3d29abc6a94c303638064d69awonjong.leevoid mix_videoformat_vc1_finalize(GObject * obj) {
90bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gint32 pret = VBP_OK;
91bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
92bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* clean up here. */
93bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
94bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MixVideoFormat *parent = NULL;
95bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *self = MIX_VIDEOFORMAT_VC1(obj);
96bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	GObjectClass *root_class = (GObjectClass *) parent_class;
97bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
98bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parent = MIX_VIDEOFORMAT(self);
99bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_mutex_lock(parent->objectlock);
101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//surfacepool is deallocated by parent
103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//inputbufqueue is deallocated by parent
104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//parent calls vaDestroyConfig, vaDestroyContext and vaDestroySurfaces
105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Unref our reference frames
107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int i = 0;
108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (; i < 2; i++)
109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (self->reference_frames[i] != NULL)
111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_unref(self->reference_frames[i]);
113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			self->reference_frames[i] = NULL;
114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Reset state
118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parent->initialized = TRUE;
119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parent->parse_in_progress = FALSE;
120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->discontinuity_frame_in_progress = FALSE;
121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->current_timestamp = 0;
122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Close the parser
124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        pret = vbp_close(parent->parser_handle);
125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->parser_handle = NULL;
126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (pret != VBP_OK)
127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error closing parser\n");
129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_mutex_unlock(parent->objectlock);
132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chain up parent */
134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (root_class->finalize) {
135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		root_class->finalize(obj);
136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
139bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMixVideoFormat_VC1 *
140bd8388b4555645b3d29abc6a94c303638064d69awonjong.leemix_videoformat_vc1_ref(MixVideoFormat_VC1 * mix) {
141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return (MixVideoFormat_VC1 *) g_object_ref(G_OBJECT(mix));
142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee/*  VC1 vmethods implementation */
145bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_getcaps(MixVideoFormat *mix, GString *msg) {
146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_NOTIMPL;
148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//This method is reserved for future use
150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix == NULL || msg == NULL)
152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "NUll pointer passed in\n");
154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->getcaps) {
163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = parent_class->getcaps(mix, msg);
164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
171bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_update_seq_header(
172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoConfigParamsDec* config_params,
173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixIOVec *header)
174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint width = 0;
176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint height = 0;
177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint i = 0;
179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guchar* p = header->data;
180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT res = MIX_RESULT_SUCCESS;
181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!config_params || !header)
183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "NUll pointer passed in\n");
185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return (MIX_RESULT_NULL_PTR);
186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	res = mix_videoconfigparamsdec_get_picture_res(
189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		config_params,
190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		&width,
191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 	&height);
192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (MIX_RESULT_SUCCESS != res)
194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return res;
196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Check for start codes.  If one exist, then this is VC-1 and not WMV. */
199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	while (i < header->data_size - 2)
200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	{
201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    		if ((p[i] == 0) &&
202bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		    (p[i + 1] == 0) &&
203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                    (p[i + 2] == 1))
204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    		{
205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      			return MIX_RESULT_SUCCESS;
206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    		}
207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    		i++;
208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	}
209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	p = g_malloc0(header->data_size + 9);
211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!p)
213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Cannot allocate memory\n");
215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return MIX_RESULT_NO_MEMORY;
216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* If we get here we have 4+ bytes of codec data that must be formatted */
219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	/* to pass through as an RCV sequence header. */
220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	p[0] = 0;
221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	p[1] = 0;
222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	p[2] = 1;
223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	p[3] = 0x0f;  /* Start code. */
224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 	p[4] = (width >> 8) & 0x0ff;
226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	p[5] = width & 0x0ff;
227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	p[6] = (height >> 8) & 0x0ff;
228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	p[7] = height & 0x0ff;
229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	memcpy(p + 8, header->data, header->data_size);
231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	*(p + header->data_size + 8) = 0x80;
232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee  	g_free(header->data);
234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	header->data = p;
235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	header->data_size = header->data_size + 9;
236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
242bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_initialize(MixVideoFormat *mix,
243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                MixVideoConfigParamsDec * config_params,
244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                MixFrameManager * frame_mgr,
245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixBufferPool * input_buf_pool,
246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixSurfacePool ** surface_pool,
247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		VADisplay va_display) {
248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        uint32 pret = 0;
250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MIX_RESULT ret = MIX_RESULT_SUCCESS;
251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        enum _vbp_parser_type ptype = VBP_VC1;
252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				vbp_data_vc1 *data = NULL;
253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MixVideoFormat *parent = NULL;
254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MixVideoFormat_VC1 *self = NULL;
255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MixIOVec *header = NULL;
256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        gint numprofs = 0, numactualprofs = 0;
257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        gint numentrypts = 0, numactualentrypts = 0;
258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        VADisplay vadisplay = NULL;
259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        VAProfile *profiles = NULL;
260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        VAEntrypoint *entrypts = NULL;
261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        VAConfigAttrib attrib;
262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        VAStatus vret = VA_STATUS_SUCCESS;
263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint extra_surfaces = 0;
264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VASurfaceID *surfaces = NULL;
265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint numSurfaces = 0;
266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//TODO Partition this method into smaller methods
268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (mix == NULL || config_params == NULL || frame_mgr == NULL || !input_buf_pool || !surface_pool || !va_display)
270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "NUll pointer passed in\n");
272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return MIX_RESULT_NULL_PTR;
273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Begin\n");
276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->initialize) {
281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = parent_class->initialize(mix, config_params,
282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				frame_mgr, input_buf_pool, surface_pool,
283bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				va_display);
284bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
285bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
286bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
287bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
288bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return ret;
289bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
290bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
291bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (!MIX_IS_VIDEOFORMAT_VC1(mix))
292bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return MIX_RESULT_INVALID_PARAM;
293bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
294bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        parent = MIX_VIDEOFORMAT(mix);
295bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self = MIX_VIDEOFORMAT_VC1(mix);
296bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
297bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Locking\n");
298bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//From now on, we exit this function through cleanup:
299bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_mutex_lock(parent->objectlock);
300bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
301bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Load the bitstream parser
302bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        pret = vbp_open(ptype, &(parent->parser_handle));
303bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
304bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (!(pret == VBP_OK))
305bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
306bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
307bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error opening parser\n");
308bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
309bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
310bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
311bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Opened parser\n");
312bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
313bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        ret = mix_videoconfigparamsdec_get_header(config_params,
314bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                &header);
315bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
316bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if ((ret != MIX_RESULT_SUCCESS) || (header == NULL))
317bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
318bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
319bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Cannot get header data\n");
320bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
321bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
322bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
323bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        ret = mix_videoconfigparamsdec_get_extra_surface_allocation(config_params,
324bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                &extra_surfaces);
325bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
326bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (ret != MIX_RESULT_SUCCESS)
327bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
328bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
329bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Cannot get extra surface allocation setting\n");
330bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
331bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
332bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
333bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Calling parse on header data, handle %d\n", (int)parent->parser_handle);
334bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
335bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_videofmt_vc1_update_seq_header(
336bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		config_params,
337bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		 header);
338bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (ret != MIX_RESULT_SUCCESS)
339bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
340bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
341bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error updating sequence header\n");
342bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
343bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
344bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
345bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        pret = vbp_parse(parent->parser_handle, header->data,
346bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        header->data_size, TRUE);
347bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
348bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (!((pret == VBP_OK) || (pret == VBP_DONE)))
349bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
350bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
351bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error parsing header data, size %d\n", header->data_size);
352bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
353bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
354bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
355bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
356bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Parsed header\n");
357bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       //Get the header data and save
358bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        pret = vbp_query(parent->parser_handle, (void *)&data);
359bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
360bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((pret != VBP_OK) || (data == NULL))
361bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
362bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
363bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error reading parsed header data\n");
364bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
365bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
366bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
367bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Queried parser for header data\n");
368bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
369bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Time for libva initialization
370bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
371bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vadisplay = parent->va_display;
372bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
373bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        numprofs = vaMaxNumProfiles(vadisplay);
374bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        profiles = g_malloc(numprofs*sizeof(VAProfile));
375bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
376bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!profiles)
377bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
378bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_NO_MEMORY;
379bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error allocating memory\n");
380bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
381bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
382bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
383bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaQueryConfigProfiles(vadisplay, profiles,
384bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                &numactualprofs);
385bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!(vret == VA_STATUS_SUCCESS))
386bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
387bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
388bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing video driver\n");
389bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
390bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
391bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
392bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //check the desired profile support
393bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        gint vaprof = 0;
394bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
395bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VAProfile profile;
396bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	switch (data->se_data->PROFILE)
397bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
398bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case 0:
399bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		profile = VAProfileVC1Simple;
400bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		break;
401bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
402bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case 1:
403bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		profile = VAProfileVC1Main;
404bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		break;
405bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
406bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		default:
407bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		profile = VAProfileVC1Advanced;
408bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		break;
409bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
410bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
411bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (; vaprof < numactualprofs; vaprof++)
412bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
413bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (profiles[vaprof] == profile)
414bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
415bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
416bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vaprof >= numprofs || profiles[vaprof] != profile)
417bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Did not get the profile we wanted
418bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
419bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
420bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Profile not supported by driver\n");
421bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
422bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
423bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
424bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        numentrypts = vaMaxNumEntrypoints(vadisplay);
425bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        entrypts = g_malloc(numentrypts*sizeof(VAEntrypoint));
426bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
427bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!entrypts)
428bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
429bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_NO_MEMORY;
430bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error allocating memory\n");
431bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
432bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
433bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
434bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaQueryConfigEntrypoints(vadisplay, profiles[vaprof],
435bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                entrypts, &numactualentrypts);
436bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!(vret == VA_STATUS_SUCCESS))
437bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
438bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
439bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing driver\n");
440bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
441bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
442bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
443bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        gint vaentrypt = 0;
444bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        for (; vaentrypt < numactualentrypts; vaentrypt++)
445bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
446bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                if (entrypts[vaentrypt] == VAEntrypointVLD)
447bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        break;
448bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
449bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vaentrypt >= numentrypts || entrypts[vaentrypt] != VAEntrypointVLD)
450bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Did not get the entrypt we wanted
451bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
452bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
453bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Entry point not supported by driver\n");
454bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
455bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
456bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
457bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //We are requesting RT attributes
458bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        attrib.type = VAConfigAttribRTFormat;
459bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
460bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaGetConfigAttributes(vadisplay, profiles[vaprof],
461bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                entrypts[vaentrypt], &attrib, 1);
462bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
463bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //TODO Handle other values returned for RT format
464bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // and check with requested format provided in config params
465bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Right now only YUV 4:2:0 is supported by libva
466bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        // and this is our default
467bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (((attrib.value & VA_RT_FORMAT_YUV420) == 0) ||
468bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                vret != VA_STATUS_SUCCESS)
469bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
470bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
471bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing driver\n");
472bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
473bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
474bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
475bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Initialize and save the VA config ID
476bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaCreateConfig(vadisplay, profiles[vaprof],
477bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                entrypts[vaentrypt], &attrib, 1, &(parent->va_config));
478bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
479bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!(vret == VA_STATUS_SUCCESS))
480bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
481bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
482bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing driver\n");
483bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
484bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
485bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
486bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Created libva config with profile %d\n", vaprof);
487bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
488bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Check for loop filtering
489bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (data->se_data->LOOPFILTER == 1)
490bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->loopFilter = TRUE;
491bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	else
492bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->loopFilter = FALSE;
493bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
494bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "loop filter is %d, TFCNTRFLAG is %d\n", data->se_data->LOOPFILTER, data->se_data->TFCNTRFLAG);
495bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
496bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       //Initialize the surface pool
497bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
498bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
499bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((data->se_data->MAXBFRAMES > 0) || (data->se_data->PROFILE == 3) || (data->se_data->PROFILE == 1))
500bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//If Advanced profile, have to assume B frames may be present, since MAXBFRAMES is not valid for this prof
501bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->haveBframes = TRUE;
502bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	else
503bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->haveBframes = FALSE;
504bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
505bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Calculate VC1 numSurfaces based on max number of B frames or
506bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// MIX_VIDEO_VC1_SURFACE_NUM, whichever is less
507bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
508bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Adding 1 to work around VBLANK issue
509bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->va_num_surfaces = 1 + extra_surfaces + ((3 + (self->haveBframes ? 1 : 0) <
510bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MIX_VIDEO_VC1_SURFACE_NUM) ?
511bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		(3 + (self->haveBframes ? 1 : 0))
512bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		: MIX_VIDEO_VC1_SURFACE_NUM);
513bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
514bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	numSurfaces = parent->va_num_surfaces;
515bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
516bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->va_surfaces = g_malloc(sizeof(VASurfaceID)*numSurfaces);
517bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
518bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	surfaces = parent->va_surfaces;
519bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
520bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (surfaces == NULL)
521bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
522bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
523bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Cannot allocate temporary data\n");
524bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
525bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
526bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
527bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaCreateSurfaces(vadisplay, parent->picture_width,
528bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                parent->picture_height, entrypts[vaentrypt],
529bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                numSurfaces, surfaces);
530bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!(vret == VA_STATUS_SUCCESS))
531bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
532bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
533bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error allocating surfaces\n");
534bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
535bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
536bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
537bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->surfacepool = mix_surfacepool_new();
538bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	*surface_pool = parent->surfacepool;
539bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
540bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent->surfacepool == NULL)
541bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
542bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
543bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing surface pool\n");
544bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
545bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
546bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
547bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
548bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        ret = mix_surfacepool_initialize(parent->surfacepool,
549bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                surfaces, numSurfaces);
550bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
551bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        switch (ret)
552bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        {
553bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                case MIX_RESULT_SUCCESS:
554bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        break;
555bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                case MIX_RESULT_ALREADY_INIT:
556bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                default:
557bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_ALREADY_INIT;
558bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Error init failure\n");
559bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
560bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                        break;
561bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
562bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
563bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Created %d libva surfaces, MAXBFRAMES is %d\n", numSurfaces, data->se_data->MAXBFRAMES);
564bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
565bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Initialize and save the VA context ID
566bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //Note: VA_PROGRESSIVE libva flag is only relevant to MPEG2
567bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        vret = vaCreateContext(vadisplay, parent->va_config,
568bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                parent->picture_width, parent->picture_height,
569bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                0, surfaces, numSurfaces,
570bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                &(parent->va_context));
571bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!(vret == VA_STATUS_SUCCESS))
572bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
573bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
574bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error initializing video driver\n");
575bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
576bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
577bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
578bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "Created libva context width %d, height %d\n", parent->picture_width, parent->picture_height);
579bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
580bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "mix_video vinfo:  Content type %s, %s\n", (header->data_size > 8) ? "VC-1" : "WMV", (data->se_data->INTERLACE) ? "interlaced" : "progressive");
581bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "mix_video vinfo:  Content width %d, height %d\n", parent->picture_width, parent->picture_height);
582bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "mix_video vinfo:  MAXBFRAMES %d (note that for Advanced profile, MAXBFRAMES can be zero and there still can be B frames in the content)\n", data->se_data->MAXBFRAMES);
583bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "mix_video vinfo:  PROFILE %d, LEVEL %d\n", data->se_data->PROFILE, data->se_data->LEVEL);
584bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
585bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
586bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	cleanup:
587bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS) {
588bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pret = vbp_close(parent->parser_handle);
589bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		parent->parser_handle = NULL;
590bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       		parent->initialized = FALSE;
591bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
592bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	} else {
593bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	         parent->initialized = TRUE;
594bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
595bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
596bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (header != NULL)
597bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
598bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (header->data != NULL)
599bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			g_free(header->data);
600bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		g_free(header);
601bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		header = NULL;
602bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
603bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
604bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_free(profiles);
605bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_free(entrypts);
606bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
607bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	self->lastFrame = NULL;
608bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
609bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
610bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Unlocking\n");
611bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_mutex_unlock(parent->objectlock);
612bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
613bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        LOG_V( "End\n");
614bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
615bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
616bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
617bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
618bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_decode(MixVideoFormat *mix,
619bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixBuffer * bufin[], gint bufincnt,
620bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                MixVideoDecodeParams * decode_params) {
621bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
622bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        uint32 pret = 0;
623bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int i = 0;
624bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        MixVideoFormat *parent = NULL;
625bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_SUCCESS;
626bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint64 ts = 0;
627bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vbp_data_vc1 *data = NULL;
628bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gboolean discontinuity = FALSE;
629bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixInputBufferEntry *bufentry = NULL;
630bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
631bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (mix == NULL || bufin == NULL || decode_params == NULL )
632bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
633bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "NUll pointer passed in\n");
634bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return MIX_RESULT_NULL_PTR;
635bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
636bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
637bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        //TODO remove iovout and iovoutcnt; they are not used (need to remove from MixVideo/MI-X API too)
638bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
639bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
640bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
641bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
642bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		We are not chaining up to parent method for now.
643bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
644bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
645bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#if 0
646bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        if (parent_class->decode) {
647bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return parent_class->decode(mix, bufin, bufincnt,
648bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                                        decode_params);
649bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
650bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
651bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
652bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!MIX_IS_VIDEOFORMAT_VC1(mix))
653bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                return MIX_RESULT_INVALID_PARAM;
654bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
655bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent = MIX_VIDEOFORMAT(mix);
656bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
657bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
658bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_videodecodeparams_get_timestamp(decode_params,
659bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&ts);
660bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
661bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
662bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
663bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
664bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
665bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_videodecodeparams_get_discontinuity(decode_params,
666bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&discontinuity);
667bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
668bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
669bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_FAIL;
670bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
671bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
672bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//From now on, we exit this function through cleanup:
673bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
674bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Locking\n");
675bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_mutex_lock(parent->objectlock);
676bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
677bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//If this is a new frame and we haven't retrieved parser
678bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//  workload data from previous frame yet, do so
679bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((ts != parent->current_timestamp) &&
680bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			(parent->parse_in_progress))
681bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
682bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
683bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//query for data
684bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pret = vbp_query(parent->parser_handle,
685bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			(void *) &data);
686bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
687bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if ((pret != VBP_OK) || (data == NULL))
688bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	{
689bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_FAIL;
690bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Error initializing parser\n");
691bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee               		goto cleanup;
692bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	}
693bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
694bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Queried for last frame data\n");
695bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
696bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//process and decode data
697bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = mix_videofmt_vc1_process_decode(mix,
698bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			data, parent->current_timestamp,
699bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			parent->discontinuity_frame_in_progress);
700bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
701bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (ret != MIX_RESULT_SUCCESS)
702bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	{
703bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//We log this but need to process the new frame data, so do not return
704bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "process_decode failed.\n");
705bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	}
706bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
707bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Called process and decode for last frame\n");
708bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
709bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		parent->parse_in_progress = FALSE;
710bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
711bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
712bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
713bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->current_timestamp = ts;
714bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	parent->discontinuity_frame_in_progress = discontinuity;
715bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
716bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Starting current frame %d, timestamp %"G_GINT64_FORMAT"\n", mix_video_vc1_counter++, ts);
717bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
718bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (i = 0; i < bufincnt; i++)
719bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
720bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
721bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Calling parse for current frame, parse handle %d, buf %x, size %d\n", (int)parent->parser_handle, (guint)bufin[i]->data, bufin[i]->size);
722bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
723bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pret = vbp_parse(parent->parser_handle,
724bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufin[i]->data,
725bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufin[i]->size,
726bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			FALSE);
727bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
728bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Called parse for current frame\n");
729bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
730bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (pret == VBP_DONE)
731bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
732bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//query for data
733bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pret = vbp_query(parent->parser_handle,
734bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				(void *) &data);
735bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
736bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if ((pret != VBP_OK) || (data == NULL))
737bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		{
738bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = MIX_RESULT_FAIL;
739bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "Error getting parser data\n");
740bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee               			goto cleanup;
741bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		}
742bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
743bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Called query for current frame\n");
744bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
745bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Increase the ref count of this input buffer
746bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_buffer_ref(bufin[i]);
747bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
748bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Create a new MixInputBufferEntry
749bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//TODO make this from a pool to optimize
750bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry = g_malloc(sizeof(
751bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				MixInputBufferEntry));
752bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (bufentry == NULL)
753bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		{
754bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = MIX_RESULT_NO_MEMORY;
755bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "Error allocating bufentry\n");
756bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee               			goto cleanup;
757bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		}
758bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
759bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry->buf = bufin[i];
760bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Setting bufentry %x for mixbuffer %x ts to %"G_GINT64_FORMAT"\n", (guint)bufentry, (guint)bufentry->buf, ts);
761bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry->timestamp = ts;
762bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
763bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Enqueue this input buffer for current frame\n");
764bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "bufentry->timestamp %"G_GINT64_FORMAT"\n", bufentry->timestamp);
765bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
766bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Enqueue this input buffer
767bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			g_queue_push_tail(parent->inputbufqueue,
768bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				(gpointer)bufentry);
769bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
770bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//process and decode data
771bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = mix_videofmt_vc1_process_decode(mix,
772bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				data, ts, discontinuity);
773bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
774bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (ret != MIX_RESULT_SUCCESS)
775bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                	{
776bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				//We log this but continue since we need to complete our processing of input buffers
777bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "Process_decode failed.\n");
778bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee                	}
779bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
780bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Called process and decode for current frame\n");
781bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
782bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			parent->parse_in_progress = FALSE;
783bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
784bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		else if (pret != VBP_OK)
785bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	{
786bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//We log this but continue since we need to complete our processing of input buffers
787bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Parsing failed.\n");
788bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_FAIL;
789bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	}
790bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		else
791bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
792bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
793bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Enqueuing buffer and going on to next (if any) for this frame\n");
794bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
795bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Increase the ref count of this input buffer
796bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_buffer_ref(bufin[i]);
797bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
798bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Create a new MixInputBufferEntry
799bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//TODO make this from a pool to optimize
800bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry = g_malloc(sizeof
801bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				(MixInputBufferEntry));
802bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (bufentry == NULL)
803bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		{
804bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = MIX_RESULT_NO_MEMORY;
805bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "Error allocating bufentry\n");
806bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee               			goto cleanup;
807bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        		}
808bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry->buf = bufin[i];
809bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			bufentry->timestamp = ts;
810bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
811bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Enqueue this input buffer
812bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			g_queue_push_tail(parent->inputbufqueue,
813bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				(gpointer)bufentry);
814bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			parent->parse_in_progress = TRUE;
815bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
816bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
817bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
818bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
819bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
820bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	cleanup:
821bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
822bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Unlocking\n");
823bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 	g_mutex_unlock(parent->objectlock);
824bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
825bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
826bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
827bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
828bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
829bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
830bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
831bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#ifdef YUVDUMP
832bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//TODO Complete this YUVDUMP code and move into base class
833bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
834bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT GetImageFromSurface (MixVideoFormat *mix, MixVideoFrame * frame)
835bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
836bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
837bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
838bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       VAStatus vaStatus = VA_STATUS_SUCCESS;
839bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       VAImageFormat va_image_format;
840bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VAImage va_image;
841bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
842bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       unsigned char*      pBuffer;
843bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       unsigned int   ui32SrcWidth = mix->picture_width;
844bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       unsigned int   ui32SrcHeight = mix->picture_height;
845bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       unsigned int   ui32Stride;
846bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       unsigned int   ui32ChromaOffset;
847bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	FILE *fp = NULL;
848bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int r = 0;
849bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
850bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       int i;
851bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
852bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       g_print ("GetImageFromSurface   \n");
853bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
854bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((mix == NULL) || (frame == NULL))
855bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
856bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
857bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
858bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
859bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
860bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	fp = fopen("yuvdump.yuv", "a+");
861bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
862bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    static int have_va_image = 0;
863bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
864bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       if (!have_va_image)
865bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       {
866bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              va_image_format.fourcc = VA_FOURCC_NV12;
867bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//              va_image_format.fourcc = VA_FOURCC_YV12;
868bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
869bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              vaStatus = vaCreateImage(mix->va_display, &va_image_format, ui32SrcWidth, ui32SrcHeight, &va_image);
870bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              have_va_image = 1;
871bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       }
872bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
873bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       vaStatus = vaGetImage( mix->va_display, frame->frame_id, 0, 0, ui32SrcWidth, ui32SrcHeight, va_image.image_id );
874bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       vaStatus = vaMapBuffer( mix->va_display, va_image.buf, (void **) &pBuffer);
875bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       ui32ChromaOffset = va_image.offsets[1];
876bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       ui32Stride = va_image.pitches[0];
877bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
878bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       if (VA_STATUS_SUCCESS != vaStatus)
879bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       {
880bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("VideoProcessBlt: Unable to copy surface\n\r");
881bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              return vaStatus;
882bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       }
883bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
884bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       {
885bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("before copy memory....\n");
886bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("width = %d, height = %d\n", ui32SrcWidth, ui32SrcHeight);
887bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("data_size = %d\n", va_image.data_size);
888bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("num_planes = %d\n", va_image.num_planes);
889bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.pitches[0] = %d\n", va_image.pitches[0]);
890bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.pitches[1] = %d\n", va_image.pitches[1]);
891bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.pitches[2] = %d\n", va_image.pitches[2]);
892bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.offsets[0] = %d\n", va_image.offsets[0]);
893bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.offsets[1] = %d\n", va_image.offsets[1]);
894bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              g_print ("va_image.offsets[2] = %d\n", va_image.offsets[2]);
895bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//      r = fwrite (pBuffer, 1, va_image.offsets[1], fp);
896bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
897bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee      r = fwrite (pBuffer, va_image.offsets[1], 1, fp);
898bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
899bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee         for (i = 0; i < ui32SrcWidth * ui32SrcHeight / 2; i +=2)
900bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              r = fwrite (pBuffer + va_image.offsets[1] + i / 2, 1, 1, fp);
901bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
902bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        for (i = 0; i < ui32SrcWidth * ui32SrcHeight / 2; i +=2)
903bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee              r = fwrite (pBuffer + va_image.offsets[1] +  i / 2 + 1, 1, 1, fp);
904bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
905bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        g_print ("ui32ChromaOffset = %d, ui32Stride = %d\n", ui32ChromaOffset, ui32Stride);
906bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
907bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       }
908bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
909bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       vaStatus = vaUnmapBuffer( mix->va_display, va_image.buf);
910bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
911bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee       return vaStatus;
912bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
913bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
914bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif /* YUVDUMP */
915bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
916bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
917bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_decode_a_picture(
918bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat* mix,
919bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vbp_data_vc1 *data,
920bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int pic_index,
921bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFrame *frame)
922bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
923bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_SUCCESS;
924bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VAStatus vret = VA_STATUS_SUCCESS;
925bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VADisplay vadisplay = NULL;
926bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VAContextID vacontext;
927bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint buffer_id_cnt = 0;
928bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VABufferID *buffer_ids = NULL;
929bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *self = MIX_VIDEOFORMAT_VC1(mix);
930bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
931bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vbp_picture_data_vc1* pic_data = &(data->pic_data[pic_index]);
932bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	VAPictureParameterBufferVC1 *pic_params = pic_data->pic_parms;
933bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
934bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (pic_params == NULL)
935bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
936bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_NULL_PTR;
937bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error reading parser data\n");
938bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
939bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
940bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
941bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "num_slices is %d, allocating %d buffer_ids\n", pic_data->num_slices, (pic_data->num_slices * 2) + 2);
942bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
943bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Set up reference frames for the picture parameter buffer
944bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
945bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Set the picture type (I, B or P frame)
946bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	enum _picture_type frame_type = pic_params->picture_fields.bits.picture_type;
947bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
948bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
949bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Check for B frames after a seek
950bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//We need to have both reference frames in hand before we can decode a B frame
951bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//If we don't have both reference frames, we must return MIX_RESULT_DROPFRAME
952bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Note:  demuxer should do the right thing and only seek to I frame, so we should
953bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//  not get P frame first, but may get B frames after the first I frame
954bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (frame_type == VC1_PTYPE_B)
955bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
956bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (self->reference_frames[1] == NULL)
957bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
958bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Insufficient reference frames for B frame\n");
959bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_DROPFRAME;
960bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
961bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
962bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
963bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
964bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	buffer_ids = g_malloc(sizeof(VABufferID) * ((pic_data->num_slices * 2) + 2));
965bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (buffer_ids == NULL)
966bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
967bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Cannot allocate buffer IDs\n");
968bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_NO_MEMORY;
969bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
970bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
971bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
972bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Getting a new surface\n");
973bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "frame type is %d\n", frame_type);
974bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
975bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gulong surface = 0;
976bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
977bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Get our surface ID from the frame object
978bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_videoframe_get_frame_id(frame, &surface);
979bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
980bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
981bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error getting surface ID from frame object\n");
982bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
983bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
984bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
985bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Get a frame from the surface pool
986bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
987bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (0 == pic_index)
988bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
989bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Set the frame type for the frame object (used in reordering by frame manager)
990bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		switch (frame_type)
991bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
992bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			case VC1_PTYPE_I:  // I frame type
993bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			case VC1_PTYPE_P:  // P frame type
994bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			case VC1_PTYPE_B:  // B frame type
995bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = mix_videoframe_set_frame_type(frame, frame_type);
996bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				break;
997bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			case VC1_PTYPE_BI: // BI frame type
998bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = mix_videoframe_set_frame_type(frame, TYPE_I);
999bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				break;
1000bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Not indicated here	case VC1_PTYPE_SKIPPED:
1001bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			default:
1002bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				break;
1003bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1004bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1005bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1006bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
1007bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1008bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error setting frame type on frame\n");
1009bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1010bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1011bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1012bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Setting reference frames in picparams, frame_type = %d\n", frame_type);
1013bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1014bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//TODO Check if we need to add more handling of B or P frames when reference frames are not set up (such as after flush/seek)
1015bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1016bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	switch (frame_type)
1017bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1018bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_I:  // I frame type
1019bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			/* forward and backward reference pictures are not used but just set to current
1020bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			surface to be in consistence with test suite
1021bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			*/
1022bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->forward_reference_picture = surface;
1023bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->backward_reference_picture = surface;
1024bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "I frame, surface ID %u\n", (guint)frame->frame_id);
1025bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "mix_video vinfo:  Frame type is I\n");
1026bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1027bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_P:  // P frame type
1028bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1029bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			// check REFDIST in the picture parameter buffer
1030bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (0 != pic_params->reference_fields.bits.reference_distance_flag &&
1031bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			    0 != pic_params->reference_fields.bits.reference_distance)
1032bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1033bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				/* The previous decoded frame (distance is up to 16 but not 0) is used
1034bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				for reference, as we don't allocate that many surfaces so the reference picture
1035bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				could have been overwritten and hence not avaiable for reference.
1036bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				*/
1037bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "reference distance is not 0!");
1038bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = MIX_RESULT_FAIL;
1039bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				goto cleanup;
1040bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1041bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (1 == pic_index)
1042bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1043bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				// handle interlace field coding case
1044bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				if (1 == pic_params->reference_fields.bits.num_reference_pictures ||
1045bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				1 == pic_params->reference_fields.bits.reference_field_pic_indicator)
1046bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1047bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					/* two reference fields or the second closest I/P field is used for
1048bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					 prediction. Set forward reference picture to INVALID so it will be
1049bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					updated to a valid previous reconstructed reference frame later.
1050bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					*/
1051bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					pic_params->forward_reference_picture  = VA_INVALID_SURFACE;
1052bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1053bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				else
1054bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1055bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					/* the closest I/P is used for reference so it must be the
1056bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					 complementary field in the same surface.
1057bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					*/
1058bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					pic_params->forward_reference_picture  = surface;
1059bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1060bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1061bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (VA_INVALID_SURFACE == pic_params->forward_reference_picture)
1062bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1063bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				if (self->reference_frames[1])
1064bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1065bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					pic_params->forward_reference_picture = self->reference_frames[1]->frame_id;
1066bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1067bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				else if (self->reference_frames[0])
1068bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1069bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					pic_params->forward_reference_picture = self->reference_frames[0]->frame_id;
1070bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1071bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				else
1072bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1073bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					ret = MIX_RESULT_FAIL;
1074bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					LOG_E( "Error could not find reference frames for P frame\n");
1075bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					goto cleanup;
1076bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1077bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1078bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->backward_reference_picture = VA_INVALID_SURFACE;
1079bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1080bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "P frame, surface ID %u, forw ref frame is %u\n", (guint)frame->frame_id, (guint)self->reference_frames[0]->frame_id);
1081bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "mix_video vinfo:  Frame type is P\n");
1082bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1083bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1084bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_B:  // B frame type
1085bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "B frame, forw ref %d, back ref %d\n", (guint)self->reference_frames[0]->frame_id, (guint)self->reference_frames[1]->frame_id);
1086bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1087bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (!self->haveBframes)	//We don't expect B frames and have not allocated a surface
1088bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee						// for the extra ref frame so this is an error
1089bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1090bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				ret = MIX_RESULT_FAIL;
1091bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_E( "Unexpected B frame, cannot process\n");
1092bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				goto cleanup;
1093bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1094bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1095bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->forward_reference_picture = self->reference_frames[0]->frame_id;
1096bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->backward_reference_picture = self->reference_frames[1]->frame_id;
1097bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1098bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "B frame, surface ID %u, forw ref %d, back ref %d\n", (guint)frame->frame_id, (guint)self->reference_frames[0]->frame_id, (guint)self->reference_frames[1]->frame_id);
1099bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "mix_video vinfo:  Frame type is B\n");
1100bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1101bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1102bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_BI:
1103bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->forward_reference_picture = VA_INVALID_SURFACE;
1104bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_params->backward_reference_picture = VA_INVALID_SURFACE;
1105bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "BI frame\n");
1106bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "mix_video vinfo:  Frame type is BI\n");
1107bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1108bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1109bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_SKIPPED:
1110bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Will never happen here
1111bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1112bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1113bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		default:
1114bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Hit default\n");
1115bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1116bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1117bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1118bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1119bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Loop filter handling
1120bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (self->loopFilter)
1121bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1122bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Setting in loop decoded picture to current frame\n");
1123bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Double checking picparams inloop filter is %d\n", pic_params->entrypoint_fields.bits.loopfilter);
1124bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pic_params->inloop_decoded_picture = frame->frame_id;
1125bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1126bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	else
1127bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1128bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Setting in loop decoded picture to invalid\n");
1129bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pic_params->inloop_decoded_picture = VA_INVALID_SURFACE;
1130bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1131bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1132bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Libva buffer set up
1133bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1134bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vadisplay = mix->va_display;
1135bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vacontext = mix->va_context;
1136bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1137bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Creating libva picture parameter buffer\n");
1138bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1139bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//First the picture parameter buffer
1140bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vret = vaCreateBuffer(
1141bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vadisplay,
1142bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vacontext,
1143bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		VAPictureParameterBufferType,
1144bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		sizeof(VAPictureParameterBufferVC1),
1145bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		1,
1146bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pic_params,
1147bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		&buffer_ids[buffer_id_cnt]);
1148bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1149bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	buffer_id_cnt++;
1150bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1151bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vret != VA_STATUS_SUCCESS)
1152bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1153bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1154bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Video driver returned error from vaCreateBuffer\n");
1155bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1156bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1157bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1158bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Creating libva bitplane buffer\n");
1159bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1160bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (pic_params->bitplane_present.value)
1161bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1162bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Then the bitplane buffer
1163bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vret = vaCreateBuffer(
1164bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vadisplay,
1165bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vacontext,
1166bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			VABitPlaneBufferType,
1167bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_data->size_bitplanes,
1168bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			1,
1169bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_data->packed_bitplanes,
1170bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&buffer_ids[buffer_id_cnt]);
1171bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1172bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		buffer_id_cnt++;
1173bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1174bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (vret != VA_STATUS_SUCCESS)
1175bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1176bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_FAIL;
1177bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Video driver returned error from vaCreateBuffer\n");
1178bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1179bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1180bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1181bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1182bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Now for slices
1183bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int i = 0;
1184bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (; i < pic_data->num_slices; i++)
1185bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1186bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Creating libva slice parameter buffer, for slice %d\n", i);
1187bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1188bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Do slice parameters
1189bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vret = vaCreateBuffer(
1190bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vadisplay,
1191bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vacontext,
1192bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			VASliceParameterBufferType,
1193bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			sizeof(VASliceParameterBufferVC1),
1194bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			1,
1195bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&(pic_data->slc_data[i].slc_parms),
1196bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&buffer_ids[buffer_id_cnt]);
1197bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1198bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (vret != VA_STATUS_SUCCESS)
1199bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1200bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_FAIL;
1201bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Video driver returned error from vaCreateBuffer\n");
1202bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1203bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1204bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1205bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		buffer_id_cnt++;
1206bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1207bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Creating libva slice data buffer for slice %d, using slice address %x, with offset %d and size %u\n", i, (guint)pic_data->slc_data[i].buffer_addr, pic_data->slc_data[i].slc_parms.slice_data_offset, pic_data->slc_data[i].slice_size);
1208bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1209bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1210bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Do slice data
1211bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vret = vaCreateBuffer(
1212bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vadisplay,
1213bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			vacontext,
1214bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			VASliceDataBufferType,
1215bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//size
1216bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_data->slc_data[i].slice_size,
1217bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//num_elements
1218bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			1,
1219bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//slice data buffer pointer
1220bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//Note that this is the original data buffer ptr;
1221bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			// offset to the actual slice data is provided in
1222bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			// slice_data_offset in VASliceParameterBufferVC1
1223bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			pic_data->slc_data[i].buffer_addr + pic_data->slc_data[i].slice_offset,
1224bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			&buffer_ids[buffer_id_cnt]);
1225bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1226bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		buffer_id_cnt++;
1227bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1228bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (vret != VA_STATUS_SUCCESS)
1229bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1230bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_FAIL;
1231bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Video driver returned error from vaCreateBuffer\n");
1232bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1233bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1234bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1235bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1236bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1237bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Calling vaBeginPicture\n");
1238bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1239bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Now we can begin the picture
1240bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vret = vaBeginPicture(vadisplay, vacontext, surface);
1241bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1242bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vret != VA_STATUS_SUCCESS)
1243bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1244bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1245bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Video driver returned error from vaBeginPicture\n");
1246bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1247bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1248bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1249bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Calling vaRenderPicture\n");
1250bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1251bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Render the picture
1252bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vret = vaRenderPicture(
1253bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vadisplay,
1254bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		vacontext,
1255bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		buffer_ids,
1256bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		buffer_id_cnt);
1257bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1258bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vret != VA_STATUS_SUCCESS)
1259bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1260bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1261bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Video driver returned error from vaRenderPicture\n");
1262bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1263bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1264bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1265bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Calling vaEndPicture\n");
1266bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1267bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//End picture
1268bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vret = vaEndPicture(vadisplay, vacontext);
1269bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1270bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vret != VA_STATUS_SUCCESS)
1271bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1272bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1273bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Video driver returned error from vaEndPicture\n");
1274bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1275bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1276bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1277bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Calling vaSyncSurface\n");
1278bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1279bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Decode the picture
1280bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vret = vaSyncSurface(vadisplay, surface);
1281bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1282bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (vret != VA_STATUS_SUCCESS)
1283bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1284bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1285bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Video driver returned error from vaSyncSurface\n");
1286bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1287bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1288bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1289bd8388b4555645b3d29abc6a94c303638064d69awonjong.leecleanup:
1290bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (NULL != buffer_ids)
1291bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		g_free(buffer_ids);
1292bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1293bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
1294bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1295bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1296bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1297bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_process_decode(
1298bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat *mix,
1299bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vbp_data_vc1 *data,
1300bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint64 timestamp,
1301bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gboolean discontinuity)
1302bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1303bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_SUCCESS;
1304bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gboolean unrefVideoFrame = FALSE;
1305bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFrame *frame = NULL;
1306bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1307bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//TODO Partition this method into smaller methods
1308bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1309bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1310bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1311bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((mix == NULL) || (data == NULL))
1312bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1313bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
1314bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
1315bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1316bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1317bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (0 == data->num_pictures || NULL == data->pic_data)
1318bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1319bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_INVALID_PARAM;
1320bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1321bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1322bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (!MIX_IS_VIDEOFORMAT_VC1(mix))
1323bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1324bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_INVALID_PARAM;
1325bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1326bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1327bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//After this point, all exits from this function are through cleanup:
1328bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *self = MIX_VIDEOFORMAT_VC1(mix);
1329bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1330bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Check for skipped frame
1331bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//For skipped frames, we will reuse the last P or I frame surface and treat as P frame
1332bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (data->pic_data[0].picture_is_skipped == VC1_PTYPE_SKIPPED)
1333bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1334bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1335bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "mix_video vinfo:  Frame type is SKIPPED\n");
1336bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (self->lastFrame == NULL)
1337bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1338bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//we shouldn't get a skipped frame before we are able to get a real frame
1339bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Error for skipped frame, prev frame is NULL\n");
1340bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_DROPFRAME;
1341bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1342bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1343bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1344bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//We don't worry about this memory allocation because SKIPPED is not a common case
1345bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Doing the allocation on the fly is a more efficient choice than trying to manage yet another pool
1346bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		MixVideoFrame *skip_frame = mix_videoframe_new();
1347bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (skip_frame == NULL)
1348bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1349bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			ret = MIX_RESULT_NO_MEMORY;
1350bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Error allocating new video frame object for skipped frame\n");
1351bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1352bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1353bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1354bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_is_skipped(skip_frame, TRUE);
1355bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//			mix_videoframe_ref(skip_frame);
1356bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_ref(self->lastFrame);
1357bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		gulong frameid = VA_INVALID_SURFACE;
1358bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_get_frame_id(self->lastFrame, &frameid);
1359bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_frame_id(skip_frame, frameid);
1360bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_frame_type(skip_frame, VC1_PTYPE_P);
1361bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_real_frame(skip_frame, self->lastFrame);
1362bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_timestamp(skip_frame, timestamp);
1363bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_discontinuity(skip_frame, FALSE);
1364bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Processing skipped frame %x, frame_id set to %d, ts %"G_GINT64_FORMAT"\n", (guint)skip_frame, (guint)frameid, timestamp);
1365bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1366bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Process reference frames
1367bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Updating skipped frame forward/backward references for libva\n");
1368bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videofmt_vc1_handle_ref_frames(mix,
1369bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				VC1_PTYPE_P,
1370bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				skip_frame);
1371bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1372bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//Enqueue the skipped frame using frame manager
1373bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = mix_framemanager_enqueue(mix->framemgr, skip_frame);
1374bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1375bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1376bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1377bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1378bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1379bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_surfacepool_get(mix->surfacepool, &frame);
1380bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
1381bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1382bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error getting frame from surfacepool\n");
1383bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1384bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1385bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1386bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	unrefVideoFrame = TRUE;
1387bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1388bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// TO DO: handle multiple frames parsed from a sample buffer
1389bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int index;
1390bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int num_pictures = (data->num_pictures > 1) ? 2 : 1;
1391bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1392bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (index = 0; index < num_pictures; index++)
1393bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1394bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = mix_videofmt_vc1_decode_a_picture(mix, data, index, frame);
1395bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (ret != MIX_RESULT_SUCCESS)
1396bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1397bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Failed to decode a picture.\n");
1398bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1399bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1400bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1401bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1402bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Set the discontinuity flag
1403bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix_videoframe_set_discontinuity(frame, discontinuity);
1404bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1405bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Set the timestamp
1406bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix_videoframe_set_timestamp(frame, timestamp);
1407bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1408bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	// setup frame structure
1409bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (data->num_pictures > 1)
1410bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1411bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (data->pic_data[0].pic_parms->picture_fields.bits.is_first_field)
1412bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_set_frame_structure(frame, VA_TOP_FIELD);
1413bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		else
1414bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_set_frame_structure(frame, VA_BOTTOM_FIELD);
1415bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1416bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	else
1417bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1418bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_set_frame_structure(frame, VA_FRAME_PICTURE);
1419bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1420bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1421bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	enum _picture_type frame_type = data->pic_data[0].pic_parms->picture_fields.bits.picture_type;
1422bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1423bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//For I or P frames
1424bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Save this frame off for skipped frame handling
1425bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((frame_type == VC1_PTYPE_I) || (frame_type == VC1_PTYPE_P))
1426bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1427bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (self->lastFrame != NULL)
1428bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1429bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_unref(self->lastFrame);
1430bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1431bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		self->lastFrame = frame;
1432bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_ref(frame);
1433bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1434bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1435bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Update the references frames for the current frame
1436bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if ((frame_type == VC1_PTYPE_I) || (frame_type == VC1_PTYPE_P))  //If I or P frame, update the reference array
1437bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1438bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Updating forward/backward references for libva\n");
1439bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videofmt_vc1_handle_ref_frames(mix,
1440bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				frame_type,
1441bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				frame);
1442bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1443bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1444bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//TODO Complete YUVDUMP code and move into base class
1445bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#ifdef YUVDUMP
1446bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix_video_vc1_counter < 10)
1447bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = GetImageFromSurface (mix, frame);
1448bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//		g_usleep(5000000);
1449bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif  /* YUVDUMP */
1450bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1451bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Enqueueing the frame with frame manager, timestamp %"G_GINT64_FORMAT"\n", timestamp);
1452bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1453bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Enqueue the decoded frame using frame manager
1454bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_framemanager_enqueue(mix->framemgr, frame);
1455bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1456bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (ret != MIX_RESULT_SUCCESS)
1457bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1458bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Error enqueuing frame object\n");
1459bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		goto cleanup;
1460bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1461bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	unrefVideoFrame = FALSE;
1462bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1463bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1464bd8388b4555645b3d29abc6a94c303638064d69awonjong.leecleanup:
1465bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1466bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix_videofmt_vc1_release_input_buffers(mix, timestamp);
1467bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (unrefVideoFrame)
1468bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_videoframe_unref(frame);
1469bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1470bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1471bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
1472bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1473bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
1474bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1475bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1476bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_flush(MixVideoFormat *mix)
1477bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1478bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_SUCCESS;
1479bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1480bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix == NULL)
1481bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1482bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
1483bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
1484bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1485bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1486bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1487bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1488bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	uint32 pret = 0;
1489bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixInputBufferEntry *bufentry = NULL;
1490bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1491bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
1492bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		We are not chaining up to parent method for now.
1493bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
1494bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1495bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#if 0
1496bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->flush)
1497bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1498bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return parent_class->flush(mix, msg);
1499bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1500bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
1501bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1502bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *self = MIX_VIDEOFORMAT_VC1(mix);
1503bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1504bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_mutex_lock(mix->objectlock);
1505bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1506bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Clear the contents of inputbufqueue
1507bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	while (!g_queue_is_empty(mix->inputbufqueue))
1508bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1509bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		bufentry = (MixInputBufferEntry *) g_queue_pop_head(mix->inputbufqueue);
1510bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (bufentry == NULL)
1511bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			continue;
1512bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1513bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_buffer_unref(bufentry->buf);
1514bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		g_free(bufentry);
1515bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1516bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1517bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Clear parse_in_progress flag and current timestamp
1518bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix->parse_in_progress = FALSE;
1519bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix->discontinuity_frame_in_progress = FALSE;
1520bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	mix->current_timestamp = 0;
1521bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1522bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	int i = 0;
1523bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	for (; i < 2; i++)
1524bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1525bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (self->reference_frames[i] != NULL)
1526bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1527bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_unref(self->reference_frames[i]);
1528bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			self->reference_frames[i] = NULL;
1529bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1530bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1531bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1532bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Call parser flush
1533bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	pret = vbp_flush(mix->parser_handle);
1534bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (pret != VBP_OK)
1535bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = MIX_RESULT_FAIL;
1536bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1537bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_mutex_unlock(mix->objectlock);
1538bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1539bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
1540bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1541bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
1542bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1543bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1544bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_eos(MixVideoFormat *mix)
1545bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1546bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MIX_RESULT ret = MIX_RESULT_SUCCESS;
1547bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	vbp_data_vc1 *data = NULL;
1548bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	uint32 pret = 0;
1549bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1550bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix == NULL)
1551bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1552bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
1553bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
1554bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1555bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1556bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1557bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1558bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1559bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
1560bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		We are not chaining up to parent method for now.
1561bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
1562bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1563bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#if 0
1564bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->eos)
1565bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1566bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return parent_class->eos(mix, msg);
1567bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1568bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee#endif
1569bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1570bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_mutex_lock(mix->objectlock);
1571bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1572bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//if a frame is in progress, process the frame
1573bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix->parse_in_progress)
1574bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1575bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//query for data
1576bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		pret = vbp_query(mix->parser_handle, (void *) &data);
1577bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1578bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if ((pret != VBP_OK) || (data == NULL))
1579bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1580bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        	ret = MIX_RESULT_FAIL;
1581bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 			LOG_E( "Error getting last parse data\n");
1582bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1583bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        }
1584bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1585bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		//process and decode data
1586bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		ret = mix_videofmt_vc1_process_decode(mix,
1587bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			data, mix->current_timestamp,
1588bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix->discontinuity_frame_in_progress);
1589bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix->parse_in_progress = FALSE;
1590bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (ret != MIX_RESULT_SUCCESS)
1591bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1592bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee 			LOG_E( "Error processing last frame\n");
1593bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			goto cleanup;
1594bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1595bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1596bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1597bd8388b4555645b3d29abc6a94c303638064d69awonjong.leecleanup:
1598bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1599bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	g_mutex_unlock(mix->objectlock);
1600bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1601bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Call Frame Manager with _eos()
1602bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	ret = mix_framemanager_eos(mix->framemgr);
1603bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1604bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
1605bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1606bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return ret;
1607bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1608bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1609bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_deinitialize(MixVideoFormat *mix)
1610bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1611bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Note this method is not called; may remove in future
1612bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix == NULL)
1613bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1614bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
1615bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
1616bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1617bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1618bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1619bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1620bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	/* Chainup parent method.
1621bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	 */
1622bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1623bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (parent_class->deinitialize)
1624bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1625bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return parent_class->deinitialize(mix);
1626bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1627bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1628bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    //Most stuff is cleaned up in parent_class->finalize() and in _finalize
1629bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1630bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    LOG_V( "End\n");
1631bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1632bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
1633bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1634bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1635bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_handle_ref_frames(
1636bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat *mix,
1637bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	enum _picture_type frame_type,
1638bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFrame * current_frame)
1639bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1640bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1641bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1642bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1643bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	if (mix == NULL || current_frame == NULL)
1644bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1645bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_E( "Null pointer passed in\n");
1646bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		return MIX_RESULT_NULL_PTR;
1647bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1648bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1649bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat_VC1 *self = MIX_VIDEOFORMAT_VC1(mix);
1650bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1651bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1652bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	switch (frame_type)
1653bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1654bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_I:  // I frame type
1655bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_P:  // P frame type
1656bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "Refing reference frame %x\n", (guint) current_frame);
1657bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			mix_videoframe_ref(current_frame);
1658bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1659bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			//If we have B frames, we need to keep forward and backward reference frames
1660bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			if (self->haveBframes)
1661bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1662bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				if (self->reference_frames[0] == NULL) //should only happen on first frame
1663bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1664bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					self->reference_frames[0] = current_frame;
1665bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee//					self->reference_frames[1] = NULL;
1666bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1667bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				else if (self->reference_frames[1] == NULL) //should only happen on second frame
1668bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1669bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					self->reference_frames[1] = current_frame;
1670bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1671bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				else
1672bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				{
1673bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					LOG_V( "Releasing reference frame %x\n", (guint) self->reference_frames[0]);
1674bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					mix_videoframe_unref(self->reference_frames[0]);
1675bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					self->reference_frames[0] = self->reference_frames[1];
1676bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					self->reference_frames[1] = current_frame;
1677bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				}
1678bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1679bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			else  //No B frames in this content, only need to keep the forward reference frame
1680bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			{
1681bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				LOG_V( "Releasing reference frame %x\n", (guint) self->reference_frames[0]);
1682bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				if (self->reference_frames[0] != NULL)
1683bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee					mix_videoframe_unref(self->reference_frames[0]);
1684bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee				self->reference_frames[0] = current_frame;
1685bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1686bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			}
1687bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1688bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_B:  // B or BI frame type (should not happen)
1689bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		case VC1_PTYPE_BI:
1690bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		default:
1691bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_E( "Wrong frame type for handling reference frames\n");
1692bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			return MIX_RESULT_FAIL;
1693bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1694bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1695bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1696bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1697bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
1698bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1699bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
1700bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1701bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1702bd8388b4555645b3d29abc6a94c303638064d69awonjong.leeMIX_RESULT mix_videofmt_vc1_release_input_buffers(
1703bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixVideoFormat *mix,
1704bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	guint64 timestamp)
1705bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee{
1706bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	MixInputBufferEntry *bufentry = NULL;
1707bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	gboolean done = FALSE;
1708bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1709bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Begin\n");
1710bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1711bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee    if (mix == NULL)
1712bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee        return MIX_RESULT_NULL_PTR;
1713bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1714bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//Dequeue and release all input buffers for this frame
1715bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1716bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "Releasing all the MixBuffers for this frame\n");
1717bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1718bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//While the head of the queue has timestamp == current ts
1719bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	//dequeue the entry, unref the MixBuffer, and free the struct
1720bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	done = FALSE;
1721bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	while (!done)
1722bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	{
1723bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		bufentry = (MixInputBufferEntry *) g_queue_peek_head(mix->inputbufqueue);
1724bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (bufentry == NULL)
1725bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1726bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1727bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "head of queue buf %x, timestamp %"G_GINT64_FORMAT", buffer timestamp %"G_GINT64_FORMAT"\n", (guint)bufentry->buf, timestamp, bufentry->timestamp);
1728bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1729bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		if (bufentry->timestamp != timestamp)
1730bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		{
1731bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			LOG_V( "buf %x, timestamp %"G_GINT64_FORMAT", buffer timestamp %"G_GINT64_FORMAT"\n", (guint)bufentry->buf, timestamp, bufentry->timestamp);
1732bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			done = TRUE;
1733bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee			break;
1734bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		}
1735bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1736bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		bufentry = (MixInputBufferEntry *) g_queue_pop_head(mix->inputbufqueue);
1737bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1738bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		LOG_V( "Unref this MixBuffers %x\n", (guint)bufentry->buf);
1739bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		mix_buffer_unref(bufentry->buf);
1740bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee		g_free(bufentry);
1741bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	}
1742bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1743bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1744bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	LOG_V( "End\n");
1745bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1746bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee	return MIX_RESULT_SUCCESS;
1747bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee}
1748bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1749bd8388b4555645b3d29abc6a94c303638064d69awonjong.lee
1750